MustEat.org

Last updated: 12:48AM 09/05/08

I ran into the problem recently where I wanted to test some code that referenced a JNDI location pull out a DataSource object to then make a connection to a DB.

The issues arises that there doesn’t appear to be a memory based Context implementation that comes with Java. This is one of the annoyances of trying to unit test JavaEE code outside JavaEE. I decided to make use of Tomcat 6’s existing InitialContextFactory implementation called javaURLContextFactory so I could bind the locations during the test setup.

I did this using the binary packages from Tomcat 6.0.18 but I expect other versions could be used as well, considering the javaURLContextFactory class has been around since 4.0

So in the classpath your tests will run under, you need to add

  • catalina.jar
  • tomcat-juli.jar

Juli is required because some logging is attempted by the Tomcat context implementation.

Next I had to wrap the InitialContextFactory to provide an implementation of InitialContextFactoryBuilder. With this class I can set the InitialContextFactory at run time through NamingManager


package test.util;

import java.util.Hashtable;

import javax.naming.NamingException;
import javax.naming.spi.InitialContextFactory;
import javax.naming.spi.InitialContextFactoryBuilder;

import org.apache.naming.java.javaURLContextFactory;

public class TomcatInitialContextFactoryBuilder implements
		InitialContextFactoryBuilder
{

	@Override
	public InitialContextFactory createInitialContextFactory(
			Hashtable<?, ?> environment) throws NamingException
	{
		return new javaURLContextFactory();
	}

}

With these libraries and this class wrapper setup, I can now setup JNDI space from inside my test suites.

Before my test runs I setup everything up.


@BeforeClass
	public static void setUpBeforeClass() throws Exception
	{
		
		
		NamingManager.setInitialContextFactoryBuilder(new TomcatInitialContextFactoryBuilder());
		Assert.assertTrue(NamingManager.hasInitialContextFactoryBuilder());
		Context ctx = new InitialContext();		
		ctx.createSubcontext("java:comp");
		ctx.createSubcontext("java:comp/env");
		ctx.createSubcontext("java:comp/env/jdbc");
		ctx.bind("java:comp/env/jdbc/<location>", <DataSource Object>);
		ctx.close();
}

And now my code can access JDBC locations it expects. Or any other JNDI location I wish to setup.

Edit:

Jason Brittain suggests ServletUnit.
You may also wish to look at Cactus

Any Suggestions? Contact Me

Tags:
weblog Tomcat 6 Tomcat Java JNDI InitialContext InitialContextFactory InitialContextFactoryBuilder Test Testing