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.
嗨Tom Anderson
Hi Tom Anderson
我尝试了以下代码
@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-内存JNDI实现或 mock JNDI实施,您会找到各种选项,或者您可以自己编写一个。基本上,你需要一个 InitialContextFactory
的实现,它只返回一个合适的mock,你可以通过设置 java.naming.factory.initial <来选择它。 / code>系统属性。
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屋!