我正在处理一些遗留代码,在这里我必须实现一个新的Handler。在这个处理程序中,有一个对象不幸地被框架使用一些硬编码的属性文件初始化,如下所示:
// new code
public class NewHandler extends RootHandler {
Util util = Util.getInstance(); // !!!Problem: throws NPE in unit-testing env
// defined in the legacy framework, can't change its signature
@Override
public void doSth() {
}
}
// legacy code
public class Util {
static public synchronized Util getInstance() {
if (_instance == null) {
_instance = new Util();
}
return _instance;
}
private Util() {
MyObj obj = LegacyCode.load("myConfig.cfg"); // !!!Problem: throws NPE in unit-testing env
...}
}
现在的问题是:
在Util()中,它总是从固定位置加载配置文件,因此当我运行单元测试时,它总是抛出NPE,因为单元测试类路径上没有"myConfig.cfg“。
一个解决方法是将业务逻辑提取到一个单独的方法中,传入一个Util对象,这样我就可以在测试期间传递模拟对象:
// new code
public class NewHandler extends RootHandler {
Util util = null;
// defined in the legacy framework, can't change its signature
@Override
public void handle() {
Util util = util.getInstance();
doHandle(util);
}
public void doHandle(Util util) {
...
}
}
// legacy code
public class Util {
...
}我的问题是:
在不添加doHandle()方法的情况下,还有其他解决这个问题的方法吗?我使用Mockito尝试了以下代码:
Util myUtil = mock(Util.class);
when(Util.getInstance()).thenReturn(myUtil);但是它没有起作用,Util.getInstance()没有被myUtil取代。
有什么想法吗?
UPDATE:事情变得有点混乱,因为我发现在遗留代码库中到处都是调用Util.getInstance()。因此,即使我的新代码中有一个模拟的Util (如下面的Stas所描述的),当Util.getInstance()在其他地方被调用时,事情仍然会中断。
显然,我不能在调用Util.getInstance()的遗留代码中的每个类中添加新的构造函数。
这就是为什么我要问“在莫基托是否可以像when(Sth.getInstance()).thenReturn(myMock)"这样的东西
如果是,那么对Util.getInstance()的所有调用都可以被模拟,不会再造成问题了。
Hmm....Any的想法?
***********************************************************************
解决方案:我认为在我的例子中解决方案是PowerMock
发布于 2011-04-19 09:50:29
你应该试试smt
public class NewHandler extends RootHandler {
Util util;
//Pass instance
NewHandler(Util util) {this.util = util;}
}而不能在测试中使用它( new NewHandler(Util.getInstance())或new NewHandler(mock(Util.class)) )。
有关服务定位器和下模的更多信息,请阅读
https://stackoverflow.com/questions/5714387
复制相似问题