正如许多人所说,单例是不好的,它是一种“反模式”。幸运的是,无论是否幸运,我使用的一些代码确实拥有它,并且它不会在不久的将来消失。所以我的问题如下。
具有状态的单例:
import java.util.HashMap;
import java.util.Map;
public enum Singleton {
INSTANCE;
private final Map<String, String> _mapper = new HashMap<String, String>();
public String getValue(String key) {
return _mapper.get(key);
}
public void addEntry(String key, String val) {
_mapper.put(key, val);
}
public String removeKey(String key) {
return _mapper.remove(key);
}
}
非常愚蠢的测试,没有考虑到在测试运行中保留单例实例状态:
import org.junit.Assert;
import org.junit.Test;
public class SingletonTest {
public static final String KEY_1 = "key_1";
@Test public void testOne() {
Singleton.INSTANCE.addEntry(KEY_1, "val_1");
Singleton.INSTANCE.addEntry("key_2", "val_2");
}
@Test public void testTwo() {
Assert.assertNull(Singleton.INSTANCE.getValue(KEY_1));
}
}
如何在测试运行之间清理状态?可以用 JUnit Runners 来完成吗?
对象的实际状态更加复杂,并通过构造函数初始化。我正在寻找类似的东西:http://powermock.googlecode.com/svn/docs/powermock-1.3.5/apidocs/org/powermock/core/classloader/annotations/PrepareForTest.html
最佳答案
您可以使用用@After
修饰的方法,该方法将在执行每个测试后执行。在此方法中,您可以清除枚举中 map 的状态:
@After
public void clear() {
Singleton.INSTANCE.removeKey(KEY_1);
Singleton.INSTANCE.removeKey("key_2");
//and on and on...
}
当然,更好的方法是在 enum
中使用 clear
方法,该方法将清除 map 的值,因此您的 @ 的正文After
方法会变得更短:
@After
public void clear() {
//assuming you can create such method
Singleton.INSTANCE.clearEntries();
}
关于java - 基于枚举的单例实现和单元测试,将状态保留为枚举的副作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23206112/