2

我有一个工厂类来检索我的应用程序的配置:

public class ConfigurationFactory {
private static ConfigurationFactory configurationFactory = new ConfigurationFactory();

private Configuration configuration = null;

public static ConfigurationFactory getConfigurationFactory() {
        return configurationFactory;
    }

还有一些 getConfiguration 方法,具体取决于我从哪里获取配置(文件、数据库、默认值等...):

public Configuration getConfiguration(String path){...}
public Configuration getConfiguration(String database){...}

我的问题是,当我对每种方法进行单元测试时,我必须重新启动单例以便从不同的源加载,所以我唯一想到的就是添加这个:

public void resetConfiguration() {
 this.configuration = null;
}

而且我觉得我会因为这样做而在开发人员的地狱中燃烧:)

我的问题:有没有其他方法可以在不添加此方法的情况下做到这一点?

注意:我已经看到,我不能使用像 Spring 或 Guice 这样的任何 DI 框架,管理层认为添加一个框架会使项目变得重量级,因为这个程序旨在作为服务器上的守护进程运行。

4

4 回答 4

1

我能想到的一些事情是

  1. 使用类似Easymock或的模拟框架Mockito来模拟ConfigurationFactory并在其他调用区域中使用这个模拟对象。

  2. ConfigurationFactory在类中定义一个 setter并定义一个注释,@TestPurpose并使用它来覆盖单元测试中的单例对象。注释表示在应用程序流程中不应使用此功能,并且该功能仅用于 junit 目的。

于 2012-05-09T06:51:36.900 回答
1

首先要解决的是你的单例不应该是静态的。这里有几篇文章向您展示如何做到这一点:

一旦你解决了这个问题,你将不再需要重置你的单例,因为你可以随意注入它们。

于 2012-05-10T04:06:10.307 回答
0

如果您不想使用建议的框架,您仍然可以拆分 'src' 和 'test-src' 并使用受保护的方法而不是公共方法。这并不理想,但可以防止调用该重置方法,同时使您能够进行测试。

  • src/main/myproject.myfactory.ConfigurationFactory
  • src/test/myproject.myfactory.TestConfigurationFactory

-> 在您的 JUnit 类中使用 @After 或 @AfterClass -方法调用重置

如果您在多个测试场景中都需要工厂,您还可以创建一个抽象的 BaseTest 类,其中包含一个 @AfterClass 方法来清理这些单例。

您也可以通过反射在您的测试代码中强制重置,并且根本不使用额外的重置方法,但我不建议这样做。

于 2014-05-05T09:14:44.847 回答
0

例如,您可以使用反射

public void resetSingleton() throws Exception {
   Field instance = FormatterService.class.getDeclaredField("instance");
   instance.setAccessible(true);
   instance.set(null, null);
}

一个例子

于 2018-05-06T13:40:38.740 回答