繁体   English   中英

Junit / Spring / Hibernate:如何在单元测试中为Hibernate Session指定容器外数据源

[英]Junit/Spring/Hibernate: How to specify an out of container datasource for Hibernate Session in Unit tests

我有一个applicationContext.xml,它定义了一个名为“ baseDataSource”的bean

<bean id="baseDataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
    <property name="resourceRef" value="true"/>
    <property name="jndiName" value="java:/MySQLDS20"/>
</bean>

现在,通常可以使用Spring和Hibernate在jboss应用程序中很好地创建它。 但是当我尝试通过实例化此IOC容器作为单元测试的一部分时

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:WEB-INF/applicationContext.xml"})

我收到此错误:

Caused by: 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 javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:662)
at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:307)
at javax.naming.InitialContext.getURLOrDefaultInitCtx(InitialContext.java:344)
at javax.naming.InitialContext.lookup(InitialContext.java:411)
at org.springframework.jndi.JndiTemplate$1.doInContext(JndiTemplate.java:154)
at org.springframework.jndi.JndiTemplate.execute(JndiTemplate.java:87)
at org.springframework.jndi.JndiTemplate.lookup(JndiTemplate.java:152)
at org.springframework.jndi.JndiTemplate.lookup(JndiTemplate.java:178)
at org.springframework.jndi.JndiLocatorSupport.lookup(JndiLocatorSupport.java:95)
at org.springframework.jndi.JndiObjectLocator.lookup(JndiObjectLocator.java:105)
at org.springframework.jndi.JndiObjectFactoryBean.lookupWithFallback(JndiObjectFactoryBean.java:201)
at org.springframework.jndi.JndiObjectFactoryBean.afterPropertiesSet(JndiObjectFactoryBean.java:187)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1477)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1417)

我已经在这里仔细阅读了讨论

http://forum.spring.io/forum/spring-projects/data/7448-problem-running-junit-test-with-jndi-datasource

但是,似乎没有任何答案可以解决问题或清楚地说明正在发生的事情。 我的问题是这样的:

如何制作此数据源? 我不能仅出于修改单个bean的目的将我的applicationContext.xml复制并粘贴到一些testApplicationContext.xml中。 在不更改此bean或不复制xml配置的情况下,如何在junit测试中创建容器和自动装配(我的CTO会杀了我)

要将自定义JNDI上下文注入到单元测试中,可以尝试以下操作:

@BeforeClass
public static void setUp() {
    DataSource ds = null; // Construct data source manually
    ds.setURL("..."); ds.setUser("..."); ds.setPassword("...");

    SimpleNamingContextBuilder builder = null;
    try {
        builder = SimpleNamingContextBuilder.emptyActivatedContextBuilder();
        builder.bind("java:java:/MySQLDS20",ds);
    } catch (NamingException e) {
        logger.error(e);
    }
}

这将通过InitialContext公开所需的JNDI名称。

但是我建议您将baseDataSource提取到单独的配置文件中,然后使用特定的配置文件进行测试。 像这样:

在src / main / resources / applicationContext.xml中:

<import resource="datasource.jndi.xml" />

JUnit测试类:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({
  "classpath*:/datasource.test.xml",
})
public class MyTests
{
    ...
}

我不能仅出于修改单个bean的目的将我的applicationContext.xml复制并粘贴到一些testApplicationContext.xml中。

不用了 您只需要创建一个仅包含数据源替代的配置,然后将两者都加载到您的测试用例中。

<bean id="dataSource" class="org.springframework.jdbc.datasource.SimpleDriverDataSource>
</bean>

然后在您的测试用例中,将其与实际文件一起加载,bean定义将覆盖实际配置中的那个。

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:WEB-INF/applicationContext.xml", "applicationContext-test.xml"})

后者应仅包含要覆盖/替换的bean。

  1. 要将自定义JNDI上下文注入到单元测试[Gregor Koukkoullis]中(这是将DataSource集成到JNDI中的好方法,但是您还需要初始化DataSource,然后注入到JNDI Context中)
  2. 您只需创建仅包含数据源替代的配置即可[M. Deinum](我认为如果可以在新的* .xml中定义数据源,那么此方法很容易实现)

但是David Williams不需要复制* .xml,目的非常清楚,无需更改配置,无需更改源代码,只需使用JNDI进行测试即可。

下面是我的方法:1.在您的远程服务器中搜索JNDI env。 2.使用setup()方法初始化您的服务器JNDI属性。

然后无需更改配置,无需更改测试代码,无需添加数据源配置,只需将设置方法添加到初始化远程服务器JNDI。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM