Junit 在应用程序服务器之外测试 JNDI InitialContext [英] Junit Testing JNDI InitialContext outside the application server
问题描述
Context context = new InitialContext();
dataSource = (DataSource) context.lookup("java:comp/env/jdbc/multiDS");
connection = dataSource.getConnection();
请帮我模拟上面的代码.
Please help me to mock the above code.
嗨汤姆安德森
我尝试了下面的代码
@BeforeClass
public static void setUpClass() throws Exception {
// rcarver - setup the jndi context and the datasource
try {
// Create initial context
System.setProperty(Context.INITIAL_CONTEXT_FACTORY,
"org.apache.naming.java.javaURLContextFactory");
System.setProperty(Context.URL_PKG_PREFIXES,
"org.apache.naming");
Context ic = new InitialContext();
ic.createSubcontext("java:");
ic.createSubcontext("java:comp");
ic.createSubcontext("java:comp/env");
ic.createSubcontext("java:comp/env/jdbc");
ic.createSubcontext("java:comp/env/jdbc/multiDS");
// Construct DataSource
OracleConnectionPoolDataSource ds = new OracleConnectionPoolDataSource();
ds.setURL("jdbc:oracle:thin:@g9u0696.houston.hp.com:1525:CRNAD");
ds.setUser("uname");
ds.setPassword("pwd");
} catch (NamingException ex) {
ex.printStackTrace();
}
}
但它给出的错误为:
com.hp.corona.common.exception.CacheException: org.apache.naming.NamingContext cannot be cast to javax.sql.DataSource
请帮我测试我只想从 JNDI 数据源连接的代码
Please help me to test the code i just want connection from JNDI datasource
推荐答案
这里的正统做法是更改您的代码,以便将 Context
注入其中(通过依赖注入框架,或手动).然后,您只需在单元测试中传递一个模拟.
The orthodox thing to do here would be to change you code so that the Context
is injected into it (by a dependency injection framework, or manually). Then, you simply pass in a mock in your unit test.
如果您不能这样做,并且您的代码必须自己创建 IntialContext
,那么您将需要设置一个虚假的 JNDI 实现,您可以在其中注入模拟.如果您在网络上搜索 in-memoryJNDI 实现 或 模拟 JNDI 实现,你会发现各种选项,或者你可以自己写一个.基本上,您将需要一个 InitialContextFactory
的实现,它只返回一个合适的模拟,然后您可以通过设置 java.naming.factory.initial
系统属性来选择它.
If you can't do this, and your code must create the IntialContext
itself, then you will need to set up a fake JNDI implementation into which you can inject mocks. If you search the web for in-memory JNDI implementation or mock JNDI implementation, you will find various options, or you could write one yourself. Basically, you will need an implementation of InitialContextFactory
which simply returns a suitable mock, which you then select by setting the java.naming.factory.initial
system property.
我无法编写必要的类.给你:
I had a crack at writing the necessary classes. Here you go:
public class MockInitialContextFactory implements InitialContextFactory {
private static final ThreadLocal<Context> currentContext = new ThreadLocal<Context>();
@Override
public Context getInitialContext(Hashtable<?, ?> environment) throws NamingException {
return currentContext.get();
}
public static void setCurrentContext(Context context) {
currentContext.set(context);
}
public static void clearCurrentContext() {
currentContext.remove();
}
}
public class MockInitialContextRule implements TestRule {
private final Context context;
public MockInitialContextRule(Context context) {
this.context = context;
}
@Override
public Statement apply(final Statement base, Description description) {
return new Statement() {
@Override
public void evaluate() throws Throwable {
System.setProperty(Context.INITIAL_CONTEXT_FACTORY, MockInitialContextFactory.class.getName());
MockInitialContextFactory.setCurrentContext(context);
try {
base.evaluate();
} finally {
System.clearProperty(Context.INITIAL_CONTEXT_FACTORY);
MockInitialContextFactory.clearCurrentContext();
}
}
};
}
}
使用如下:
public class FooTest {
private final Context context = mock(Context.class);
@Rule
public MockInitialContextRule mockInitialContextRule = new MockInitialContextRule(context);
@Test
public void testName() throws Exception {
// set up stubbings on the context mock
// invoke the code under test
}
}
这篇关于Junit 在应用程序服务器之外测试 JNDI InitialContext的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!