Aus*_*tin 14 java unit-testing initial-context
所有,
我试图在一些古老的java代码中进行一些单元测试(没有接口,没有抽象等)
这是一个使用ServletContext的servlet(我假设它是由Tomcat设置的),并且它在web.xml/context.xml文件中设置了数据库信息.现在,我已经弄清楚如何制作一个假的ServletContext,但代码有
InitialContext _ic = new InitialContext();
Run Code Online (Sandbox Code Playgroud)
到处都是(所以更换它是不可行的).我需要找到一种方法来使默认的InitialContext()能够在_ic.lookup(val)不抛出异常的情况下完成.
我假设有一些方法可以加载context.xml,但是这个魔法是如何工作的,我正在画一个空白.有人有主意吗?
小智 35
利用InitialContext使用SPI处理其创建的事实.您可以通过创建一个实现javax.naming.spi.InitialContextFactory并通过系统属性javax.naming.factory.initial(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();
}
}
}
Run Code Online (Sandbox Code Playgroud)
这个impl 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;
}
}
Run Code Online (Sandbox Code Playgroud)
使用.UseInitialContext在junit测试中创建实例
-Djava.naming.initial.factory=initial.context.test.MyInitialContext
Run Code Online (Sandbox Code Playgroud)
在命令行输出This is my object!!(易于在eclipse中设置).我喜欢Mockito嘲笑和抄袭.如果您处理大量遗留代码,我还建议Micheal Feather 有效地使用遗留代码.这一切都是关于如何在程序中找到接缝以隔离特定的测试件.
这是我为单元测试设置Inintial Context的解决方案.首先,我将以下测试依赖项添加到我的项目中:
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>catalina</artifactId>
<version>6.0.33</version>
<scope>test</scope>
</dependency>
Run Code Online (Sandbox Code Playgroud)
然后我用以下代码创建了一个静态方法:
public static void setupInitialContext() throws Exception {
System.setProperty(Context.INITIAL_CONTEXT_FACTORY, "org.apache.naming.java.javaURLContextFactory");
System.setProperty(Context.URL_PKG_PREFIXES, "org.apache.naming");
InitialContext ic = new InitialContext();
ic.createSubcontext("jdbc");
PGSimpleDataSource ds = new PGSimpleDataSource();
ds.setDatabaseName("postgres");
ds.setUser("postgres");
ds.setPassword("admin");
ic.bind("jdbc/something", ds);
}
Run Code Online (Sandbox Code Playgroud)
最后,在我的每个测试类中,我添加了一个调用setupInitialContext的@BeforeClass方法.