Reputation: 57
The production applicationContext.xml defines several beans, seen below (mostly JMS resources) that are only relevant while deployed in production. The unit tests have mock implementations that completely bypass any 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"/>
With the above in the main applicationContext.xml, I get the following exception during the tests since there is no JNDI container available.
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)
Is it possible to tell Spring not to attempt to load those beans (whose ids I know) in the test applicationContext.xml? Or have a "null bean" since I know they will never be used? This would be less work than mocking them like in How to test a mocked JNDI datasource with Spring? .
Upvotes: 2
Views: 3185
Reputation: 32949
What I suggest in general is the following. Break up your context files into multiple files. Generally isolate the beans that should not be used during testing in a separate context file. Have a single context file that imports all the bean definition files.
For your test, only load the files with the beans that you need for the test. If you have a bean A that you need for the test and depends on bean B, use Springockito's @ReplaceWithMock to mock B and inject it into the context.
In your case I would suggest moving your jndi-lookup beans into a separate context and mocking / replacing jmsConnectionFactory
or jmsTemplate
(I would lean towards replacing jmsTemplate
).
Upvotes: 2