简体   繁体   English

测试类取决于它的静态final字段

[英]Testing class dependent on it's static final field

I wonder if it is possible to test somehow class which is dependent on static final field? 我想知道是否有可能测试依赖于静态final字段的类吗? For example I have the following class: 例如,我有以下课程:

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!");
        }
    }
}

So how can I test getInstance() (I know there is nothing to test, but this is just an example) method on windows if BAR_FILE is hardcoded and equals to some unix-style path. 因此,如果BAR_FILE是硬编码的并且等于某些Unix风格的路径,那么如何在Windows上测试getInstance() (我知道没有要测试的东西,但这只是一个例子)。 I tried to change this field via reflection, but no luck, and, moreover, in accordance with this discussion it is not even possible. 我试图通过反思来改变这个领域,但是没有运气,而且,根据这个讨论,它甚至是不可能的。 Any help is appreciated! 任何帮助表示赞赏!

Separate your business logic from the constructional logic. 将您的业务逻辑与构造逻辑分开。 Your class should not care how it is created, leave that to either a factory or DI framework. 您的班级不必在意它的创建方式,而应将其留给工厂或DI框架进行。

Using a DI framework this is very easy: 使用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.
}

Using a factory is a little more effort, but not a lot. 使用工厂要花些力气,但不是很多。

// 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.
}

In both cases testing the client of Foo is easy as you can inject a mock and testing Foo is easier as you can now set the file to read (if you want to be clever don't pass in a file but a Reader or InputStream). 在这两种情况下,测试Foo的客户端都很容易,因为您可以注入一个模拟,而测试Foo则更容易,因为您现在可以将文件设置为可读(如果您想变得聪明,请不要传入文件,而应该传入Reader或InputStream) 。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM