PDA

View Full Version : JNDI and Unit testing


mperham
Aug 26th, 2004, 04:24 PM
What is the recommended way to test JNDI accessed objects within a basic unit test framework? I have a JMS topic and connection factory that I retrieve at runtime. I'd like to be able to configure ActiveMQ to run in-VM, along with a basic mocked JNDI with a bound topic and factory so that I can run the actual MQ within junit without a container. The only problem is that I can't figure out how to create a mock JNDI context within the applicationContext.xml and bind the two beans to it. Is there an easy way to do this?

Unfortunately ActiveMQ did not include mock JNDI support in v1.0 so I can't use the info included here without using a development snapshot:

http://activemq.codehaus.org/JNDI+Support

mike

Colin Sampaleanu
Aug 26th, 2004, 05:11 PM
You can try using the SimpleNamingContext mock that is included with Spring, in the spring-mock.jar file.

mperham
Aug 26th, 2004, 05:12 PM
Do you have an example of such usage? I've looked at it once or twice today but it's not obvious to me how to use it.

mperham
Aug 26th, 2004, 05:18 PM
Also, why does this mock use constructor injection instead of the standard setter-based DI pattern that other Spring beans use?

mperham
Aug 26th, 2004, 05:39 PM
This does not work, I assume because <map> returns a non-Hashtable Map whereas the SimpleNamingContext constructor expects a Hashtable.


<bean id="csaDocumentConnectionFactoryImpl"
class="org.codehaus.activemq.ActiveMQConnectionFactory">
<property name="brokerURL"><value>vm://localhost</value></property>
<property name="useEmbeddedBroker"><value>true</value></property>
</bean>

<bean id="jndiContext" class="org.springframework.mock.jndi.SimpleNamingContext">
<constructor-arg index="0"><value>java:comp/env/jms</value></constructor-arg>
<constructor-arg index="1">
<map>
<entry key="csaDocumentTCF"><ref bean="csaDocumentConnectionFactoryImpl"/></entry>
</map>
</constructor-arg>
<constructor-arg index="2"><null/></constructor-arg>
</bean>

Juergen Hoeller
Aug 27th, 2004, 02:18 AM
Have a look at the javadocs of SimpleNamingContextBuilder: It shows a usage example. Essentially, you're supposed to activate a system-wide mock JNDI environment via SimpleNamingContextBuilder, rather than using SimpleNamingContext directly. The latter is just appropriate in very specific cases.

Juergen

mperham
Aug 27th, 2004, 09:59 AM
The problem is that the usage shown uses Java code, not Spring context initialization. Instead I decided to use Sun's reference file system context and link to that in the appContext with a JndiTemplate. This way my test harnesses don't have to create their JNDI harness - it's provided to them just as under normal runtime conditions. I did have to write one-time Java code to create a .bindings file with the bound objects.


<bean id="jndiTemplate" class="org.springframework.jndi.JndiTemplate">
<property name="environment">
<props>
<prop key="java.naming.factory.initial">com.sun.jndi.fscontext.RefFSContextFactory</prop>
<prop key="java.naming.provider.url">file:./src/test</prop>
</props>
</property>
</bean>


Have a look at the javadocs of SimpleNamingContextBuilder: It shows a usage example. Essentially, you're supposed to activate a system-wide mock JNDI environment via SimpleNamingContextBuilder, rather than using SimpleNamingContext directly. The latter is just appropriate in very specific cases.

Juergen