0

static final フィールドに依存するクラスを何らかの方法でテストすることは可能でしょうか? たとえば、次のクラスがあります。

public final class Foo
{
    private static Foo instance;
    public static final String BAR_FILE = "/usr/bin/bar.bar";

    private Foo()
    {
        loadBar();
    }

    public static synchronized Foo getInstance()
    {
        if (instance == null)
        {
            instance = new Foo();
        }
        return instance;
    }

    private void loadBar()
    {
        final Properties prop = new Properties();
        try
        {
            final FileInputStream fis = new FileInputStream(BAR_FILE);
            prop.load(fis);
            fis.close();
        }
        catch (final IOException ex)
        {
            System.out.println("Exception!");
        }
    }
}

ではgetInstance()、BAR_FILE がハードコードされていて、UNIX スタイルのパスに等しい場合、Windows でメソッドをテストするにはどうすればよいでしょうか (テストするものが何もないことはわかっていますが、これは単なる例です)。私は反射を介してこのフィールドを変更しようとしましたが、うまくいきませんでした。さらに、この議論によれば、それは不可能です。どんな助けでも大歓迎です!

4

1 に答える 1

0

ビジネス ロジックを構造ロジックから分離します。クラスは、それがどのように作成されたかを気にする必要はありません。それはファクトリまたは DI フレームワークに任せてください。

DI フレームワークを使用すると、これは非常に簡単です。

@Singleton
public final class Foo {
  public Foo(String fileName) { loadBar(fileName);}  // Use in tests
  public Foo() { loadBar(DEFAULT_FILENAME);} 
  private void loadBar(String file)
    {
         // SNIP
    }
}


public class ThingieThatUsesFoo {
     public ThingieThatUsesFoo(Foo foo) { ... } // The DI framework (Guice/Spring) will handle the details of WHAT gets injected.
}

ファクトリを使用するのは少し手間がかかりますが、大したことではありません。

// You could make FooFactory a singleton if that is your thing.
public class FooFactory {
     private Foo fooInstance = new Foo();
     public Foo getFoo() {
         return fooInstance;
     }
     public void setFooForTestingOnly(Foo fooInstance) { ... } // Set this to a mock or what have thee when testing clients.
}

どちらの場合も、Foo のクライアントのテストはモックを注入できるので簡単で、Foo のテストはファイルを読み取るように設定できるので簡単です (賢くしたい場合は、ファイルではなく Reader または InputStream を渡さないでください)。 .

于 2013-07-03T15:06:09.270 に答える