防止Spring在单元测试期间实例化某些bean

时间:2014-03-17 20:59:28

标签: spring junit jndi

生产applicationContext.xml定义了几个bean,如下所示(主要是JMS资源),仅在生产中部署时才相关。单元测试具有完全绕过任何JMS的模拟实现。

<jee:jndi-lookup id="jmsConnectionFactory" jndi-name="java:/JmsXA" resource-ref="false" proxy-interface="javax.jms.ConnectionFactory"/>
<jee:jndi-lookup id="myQueue" jndi-name="java:jboss/exported/jms/queue/myQueue"/>
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
    <property name="connectionFactory" ref="jmsConnectionFactory" />
</bean>
<bean id="myMessageHandler" class="com.example.MyMessageHandler" />
<bean id="jndiDestinationResolver" class="org.springframework.jms.support.destination.JndiDestinationResolver"/>

使用上面的主applicationContext.xml,我在测试期间得到以下异常,因为没有可用的JNDI容器。

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.support.SimpleJndiBeanFactory.getBean(SimpleJndiBeanFactory.java:113)

是否有可能告诉Spring不要尝试在测试applicationContext.xml中加载那些bean(我知道哪些ID)?或者有一个“空豆”,因为我知道它们永远不会被使用?这比在How to test a mocked JNDI datasource with Spring?中嘲弄它们要少。

1 个答案:

答案 0 :(得分:2)

我的建议一般如下。将您的上下文文件分解为多个文件。通常将测试期间不应使用的bean隔离在单独的上下文文件中。有一个导入所有bean定义文件的上下文文件。

对于您的测试,仅加载具有测试所需的bean的文件。如果您有一个测试所需的bean A并且依赖于bean B,请使用Springockito's @ReplaceWithMock来模拟B并将其注入上下文。

在您的情况下,我建议将您的jndi-lookup bean移动到单独的上下文中并模拟/替换jmsConnectionFactoryjmsTemplate(我倾向于替换jmsTemplate)。