全部,
我正尝试在一些陈旧的 Java 代码(没有接口(interface)、没有抽象等)中做一些单元测试
这是一个使用 ServletContext 的 servlet(我假设它是由 Tomcat 设置的)并且它在 web.xml/context.xml 文件中设置了数据库信息。现在,我已经想出了如何制作一个 Fake ServletContext,但是代码有
InitialContext _ic = new InitialContext();
到处都是(所以替换它是不可行的)。我需要找到一种方法使默认的 InitialContext() 能够执行 _ic.lookup(val)
而不会引发异常。
我假设有某种方式可以加载 context.xml,但这个魔法是如何工作的,我画的是一片空白。有人有什么想法吗?
最佳答案
利用 InitialContext
使用 SPI 来处理其创建这一事实。您可以通过创建 javax.naming.spi.InitialContextFactory
的实现并通过系统属性 javax.naming.factory.initial
将其传递给您的测试来 Hook 其生命周期( Context.INTITIAL_CONTEXT_FACTORY
)。它比听起来简单。
给定这个类:
public class UseInitialContext {
public UseInitialContext() {
try {
InitialContext ic = new InitialContext();
Object myObject = ic.lookup("myObject");
System.out.println(myObject);
} catch (NamingException e) {
e.printStackTrace();
}
}
}
InitialContextFactory
的实现:
public class MyInitialContextFactory implements InitialContextFactory {
public Context getInitialContext(Hashtable<?, ?> arg0)
throws NamingException {
Context context = Mockito.mock(Context.class);
Mockito.when(context.lookup("myObject")).thenReturn("This is my object!!");
return context;
}
}
在
的 junit 测试中创建UseInitialContext
实例
-Djava.naming.initial.factory=initial.context.test.MyInitialContext
在命令行输出 This is my object!!
(在 eclipse 中很容易设置)。我喜欢Mockito用于 mock 和 stub 。我还推荐 Micheal Feather 的 Working Effectively with Legacy Code如果您处理大量遗留代码。这一切都是关于如何在程序中找到接缝,以便隔离特定的部分进行测试。
关于java - 如何使用默认构造函数伪造 InitialContext,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10045466/