Junit 在应用程序服务器之外测试 JNDI InitialContext [英] Junit Testing JNDI InitialContext outside the application server

查看:12
本文介绍了Junit 在应用程序服务器之外测试 JNDI InitialContext的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆