【问题标题】:How to run JUnit Test in Spring Injecting JBOSS JNDI datasources如何在 Spring 中运行 JUnit 测试注入 JBOSS JNDI 数据源
【发布时间】:2013-11-14 11:41:32
【问题描述】:

我在春季有一个在 JBOSS 7.1 上运行数据库 oracle 的应用程序。 我想简单地运行一个 junit 测试来测试我的服务层 bean。 在我的 spring 上下文中,我使用这样的 jndi 数据源:

<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
    <property name="jndiName" value="jboss/datasources/myDatasource" />
    <property name="resourceRef" value="true"/>
</bean>

当我运行加载 spring 上下文测试的 junit 测试时,我收到如下异常:

java.lang.IllegalStateException: Failed to load ApplicationContext
    at org.springframework.test.context.TestContext.getApplicationContext(TestContext.java:157)
    at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:109)
...
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in class path resource [context.xml]: Invocation of init method failed; nested exception is javax.naming.NoInitialContextException: Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file:  java.naming.factory.initial
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1455)

如何在我的测试中注入 JNDI 数据源而不改变我在 jboss 中的上下文?

【问题讨论】:

标签: java spring junit jboss jndi


【解决方案1】:

根据this 帖子或this 很棒的博文,我找到了三种解决问题的方法,只需在您的 JUnitTest 类中创建 BeforeClass 方法。

我为社区发布它:

- 解决方案 1
此解决方案需要您的类路径中的 catalina.jar 和 oracledriver:

@BeforeClass
public static void setUpClass() throws Exception {
    try {
        System.setProperty(Context.INITIAL_CONTEXT_FACTORY, "org.apache.naming.java.javaURLContextFactory");
        System.setProperty(Context.URL_PKG_PREFIXES, "org.apache.naming");            
        InitialContext ic = new InitialContext();

        ic.createSubcontext("jboss");
        ic.createSubcontext("jboss/datasources");
        ic.createSubcontext("jboss/datasources/myDatasource");

        OracleConnectionPoolDataSource ds = new OracleConnectionPoolDataSource();
        ds.setURL("jdbc:oracle:thin:@xxxxx:1521:xxxxx");
        ds.setUser("myUserid");
        ds.setPassword("myPass");

        ic.rebind("jboss/datasources/myDatasource", ds);
    } catch (NamingException ex) {
        ex.printStackTrace();
    }
}

如果你使用 maven,你可以放入你的 pom:

<dependency>
    <groupId>org.apache.tomcat</groupId>
    <artifactId>catalina</artifactId>
    <version>6.0.37</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>com.oracle</groupId>
    <artifactId>ojdbc6</artifactId>
    <version>11.2.0.3.0</version>
    <scope>test</scope>
</dependency> 


- 解决方案 2
此解决方案需要您的类路径中的 commons-dbcp:

@BeforeClass
public static void setUpDataSource() throws Exception {
    try {
        SimpleNamingContextBuilder builder = new SimpleNamingContextBuilder();
        DriverAdapterCPDS cpds = new DriverAdapterCPDS();
        cpds.setDriver("oracle.jdbc.OracleDriver");
        cpds.setUrl("jdbc:oracle:thin:@xxxxx:1521:xxxxx");
        cpds.setUser("myUsername");
        cpds.setPassword("myPass");

        SharedPoolDataSource dataSource = new SharedPoolDataSource();
        dataSource.setConnectionPoolDataSource(cpds);
        dataSource.setMaxActive(10);
        dataSource.setMaxWait(50);
        builder.bind("jboss/datasources/myDatasource", dataSource);
        builder.activate();
    } catch (NamingException ex) {
        ex.printStackTrace();
    }
}

在你的 pom 中:

<dependency>
    <groupId>commons-dbcp</groupId>
    <artifactId>commons-dbcp</artifactId>
    <version>1.4</version>
    <scope>test</scope>
</dependency>


- 解决方案 3
此解决方案使用 Oracle 驱动程序中包含的 OracleConnectionPoolDataSource:

@BeforeClass
public static void setUpDataSource() throws Exception {
    try {
        SimpleNamingContextBuilder builder = new SimpleNamingContextBuilder();

        OracleConnectionPoolDataSource ds = new OracleConnectionPoolDataSource();
        ds.setURL("jdbc:oracle:thin:@xxxxx:1521:xxxxx");
        ds.setUser("myUsername");
        ds.setPassword("myPass");           

        builder.bind("jboss/datasources/myDatasource", ds);
        builder.activate();
    } catch (NamingException ex) {
        ex.printStackTrace();
    }
}

【讨论】:

  • 可以创建从 -ds.xml 配置文件加载它们的 JNDI(其中包含 datasources 标记)。你能举一些例子吗?提前致谢。
【解决方案2】:

我的建议是分离出“基础设施”配置(DataSourcePlatformTransactionManager、...),仅在 WildFly 中部署时使用 JNDI / JTA,并使用不同的配置进行测试。您可以为此使用 Spring 条件 bean,也可以以不同的方式构建应用程序上下文。

【讨论】:

    猜你喜欢
    • 2013-05-09
    • 2012-10-14
    • 2011-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-23
    • 2011-08-21
    相关资源
    最近更新 更多