我试图想出最好的方法来测试我当前正在使用的缓存类....我希望在测试中运行此类时替换下面的ClientFactory ....我想留下结构尽可能多的类,但因为它有一个私人构造函数我很难想到最好的测试方法..
public class MyCache {
private final long TIME_OUT
private static MyCache instance = null;
private final HashMap<String, MyObject> cache = new HashMap<String, MyObject>();
private MyCache() {
}
public static MyCache getInstance() {
if (instance == null) {
instance = new MyCache();
}
return instance;
}
public MyObject getDetails(String id) throws Exception {
MyObject myObject = cache.get(id);
if (myObject != null) {
return myObject;
} else {
try {
// want to be able to replace ClientFactory with test stub
Client client = ClientFactory.createClient();
myObject = client.getMyObject(id);
} catch (NotFoundException nf) {
.... log error
}
return myObject;
}
}
}
答案 0 :(得分:1)
你可以做很多事情,但我认为从测试的角度看,Singleton-pattern不是一个好的选择。
如果您使用的是 Mockito ,则应将ClientFactory.createClient()
调用解压缩到package-public(默认)函数中。 Mockito可以监视单身人士:spy(MyCache.class)
,你可以改变提取函数的行为。所以你替换了ClientFactory
。
您可以使用package-public构造函数替换private
构造函数,还需要提取第一个解决方案中提到的函数。完成这些更改后,您可以在测试类中扩展MyCache
(不使用 Mockito )。
您可以将MyCache
的功能提取到包公共类中,该类不是单例(但不能从外部调用)。您可以很好地测试它,MyCache
将只是提取类的单独包装。
我认为反射是反模式的,但我知道默认访问修饰符(空字符串)也有点难看。
关于你的单身人士模式的几句话。如果您只有一个线程,这可不错,但如果您处于多线程环境中,则需要以下代码:
// you need volatile, because of JVM thread caching
private static volatile MyCache instance;
private MyCache() {}
public static MyCache getInstance() {
if (instance == null) {
synchronize(MyCache.class) {
// yes, you need double check, because of threads
if (instance == null) {
instance = new MyCache();
}
}
}
return instance;
}