Context context = new InitialContext(); dataSource = (DataSource) context.lookup("java:comp/env/jdbc/multiDS"); connection = dataSource.getConnection();
请帮我嘲笑上面的代码.
你好,汤姆·安德森
我试了下面的代码
@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数据源连接的代码
解决方法
在这里做的正统的事情是改变你的代码,以便将Context注入它(通过依赖注入框架,或手动).然后,您只需在单元测试中通过模拟.
如果你不能这样做,你的代码必须创建IntialContext本身,那么你将需要设置一个假的JNDI实现,你可以在其中注入mocks.如果您在网上搜索“内存中的JNDI实现”或“模拟JNDI实现”,您会发现各种选项,或者您可以自己编写一个.基本上,您将需要一个InitialContextFactory的实现,它只返回一个合适的模拟,然后您可以通过设置java.naming.factory.initial系统属性来选择.
我在写必要的课程时遇到了一个裂缝.干得好:
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; private 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 } }