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