用jUnit测试单例
我有一个工厂类来检索我的应用程序的配置:
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){...}
我的问题是,当我为每个方法进行unit testing时,我必须重新启动单例以便从不同的源加载,所以我唯一想到的就是添加这个:
public void resetConfiguration() { this.configuration = null; }
我觉得我会因为这样做而烧掉开发人员的地狱:)
我的问题:没有添加此方法,还有其他方法吗?
注意:我已经看到了这个 ,我不能使用像Spring或Guice这样的任何DI框架,管理层认为添加一个框架会使项目变得重量级,因为这个程序旨在作为服务器上的守护进程运行。
我能想到的一些事情是
-
使用像
Easymock
或Mockito
这样的模拟框架来模拟ConfigurationFactory
并在其他调用区域中使用这个模拟对象。 -
在
ConfigurationFactory
类中定义一个setter并定义一个类似@TestPurpose
的注释,并使用它来覆盖unit testing中的singleton对象。 注释是表示在应用程序流程中不应该使用它,并且该函数仅用于junit目的。
要解决的第一件事是你的单身人不应该是静态的。 这里有几篇文章向您展示如何做到这一点:
- 恢复单身人士模式 。
- dependency injection 。
一旦你解决了这个问题,你将不再需要重置你的单身,因为你可以随意注射它们。
如果您不想使用建议的框架,您仍然可以将“src”和“test-src”拆分并使用受保护的方法而不是公共方法。 这不是理想的,但在允许您测试的同时阻止调用该重置方法。
- 的src /主/ myproject.myfactory.ConfigurationFactory
- 的src /测试/ myproject.myfactory.TestConfigurationFactory
– >在你的JUnit-class中使用@After或@AfterClass -methods来调用reset
如果您需要在多个测试场景中使用Factory,您还可以创建一个抽象的BaseTest类,其中包含一个@AfterClass方法来清理这些单例。
您也可以通过测试代码中的reflection强制执行重置,并且根本不使用额外的重置方法,但我不建议这样做。
例如,您可以使用reflection
public void resetSingleton() throws Exception { Field instance = FormatterService.class.getDeclaredField("instance"); instance.setAccessible(true); instance.set(null, null); }
看一个例子