我试图提出最好的方法来测试当前正在使用的缓存类....当我在测试中运行该类时,我想在下面替换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;
}
}
}
您可以做很多事情,但是从测试的角度来看,单例模式不是一个好选择。
如果使用的是Mockito,则应将ClientFactory.createClient()
调用提取到package-public(默认)函数中。Mockito可以监视单例:spy(MyCache.class)
,并且您可以更改提取函数的行为。因此,您更换了ClientFactory
。
您可以将您的private
构造函数替换为package-public构造函数,并且还需要提取第一个解决方案中提到的函数。完成这些更改后,您可以扩展MyCache
测试类(不使用Mockito)。
您可以将的功能提取MyCache
到package-public类中,该类不是单例的(但不能从外部调用)。您可以很好地对其进行测试,并且它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;
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句