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

查看:167
本文介绍了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.

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

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