生产 applicationContext.xml 定义了几个 bean,如下所示(主要是 JMS 资源),这些 bean 仅在生产中部署时相关。单元测试具有完全绕过任何 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)?或者有一个“null bean”,因为我知道它们永远不会被使用?这比像 How to test a mocked JNDI datasource with Spring? 中那样 mock 它们要少一些工作。 .
最佳答案
我的一般建议如下。将上下文文件分解为多个文件。通常将测试期间不应使用的 bean 隔离在单独的上下文文件中。有一个导入所有 bean 定义文件的上下文文件。
对于您的测试,仅加载包含测试所需的 Bean 的文件。如果您有测试所需的 bean A 并且依赖于 bean B,请使用 Springockito's @ReplaceWithMock模拟 B 并将其注入(inject)到上下文中。
在你的情况下,我建议将你的 jndi-lookup beans 移动到一个单独的上下文中并模拟/替换 jmsConnectionFactory
或 jmsTemplate
(我倾向于替换 jmsTemplate
)。
关于spring - 防止 Spring 在单元测试期间实例化某些 bean,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22465265/