用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框架,管理层认为添加一个框架会使项目变得重量级,因为这个程序旨在作为服务器上的守护进程运行。

我能想到的一些事情是

  1. 使用像EasymockMockito这样的模拟框架来模拟ConfigurationFactory并在其他调用区域中使用这个模拟对象。

  2. 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); } 

看一个例子