in Uncategorized

Creating Integration Tests with JNDI

Technically speaking, an automated test that requires JNDI is not a unit test. As an aside, it is preferrable to segregate the portions of the application accessing JNDI to leave as much of the application unit testing as possible. Nevertheless, if JNDI is used, something must ultimately do it and it is preferrable to be able to test this code prior to its us in production.

So far, the best starting point for me has been to use Simple JNDI to create the provider and allow the rest of the code to work unimpeded. The original Simple JNDI project decayed a little bit. An update with bug fixes is available on github with a different group id (https://github.com/h-thurow/Simple-JNDI). I also used H2’s in-memory database so that I could put real connection information in the test case.

To get started, I added these dependencies to my pom.xml:

  <dependency>
      <groupId>com.github.h-thurow</groupId>
      <artifactId>simple-jndi</artifactId>
      <version>0.12.0</version>
      <scope>test</scope>
  </dependency>
<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <version>1.4.192</version>
    <scope>test</scope>
</dependency>

It took some trial and error to get the configuration right, which is one of the motivations for this writeup. The first thing you need is to add a jndi.properties file to your test resources. The settings I will discuss below were chosen to emulate the Tomcat Server setup that we use here.

java.naming.factory.initial = org.osjava.sj.SimpleContextFactory
org.osjava.sj.root=target/test-classes/config/
org.osjava.sj.space=java:/comp
#org.osjava.sj.jndi.shared=true
org.osjava.sj.delimiter=/

Notice that the root is given relative to the pom. This is one thing that caused me a great deal of grief on the first pass. Another important element was the use of the space option, which was needed to emulate Tomcat’s environment. Within the test resources, I added a config folder, containing a single file: env.properties. This latter file had contents like the following:

org.example.mydatasource/type=javax.sql.DataSource
org.example.mydatasource/url=jdbc:h2:mem:
org.example.mydatasource/driver=org.h2.Driver
org.example.mydatasource/user=
org.example.mydatasource/password=

The data source in question did indeed have a dotted name, which only added to some of the initial confusion. This allowed my code-under-test to work as anticipated. For reference’s sake, this is what the Java code looked like:

private DataSource retrieveDataSource() {
    try {
        Context initContext = new InitialContext();
        Context envContext  = (Context)initContext.lookup("java:/comp/env");

        return (DataSource)envContext.lookup(DATA_SOURCE_NAME);
    } catch(NamingException e) {
        log.error("Error attempting to find data source", e);
        return null;
    }
}

Sources

Write a Comment

Comment

To create code blocks or other preformatted text, indent by four spaces:

    This will be displayed in a monospaced font. The first four 
    spaces will be stripped off, but all other whitespace
    will be preserved.
    
    Markdown is turned off in code blocks:
     [This is not a link](http://example.com)

To create not a block, but an inline code span, use backticks:

Here is some inline `code`.

For more help see http://daringfireball.net/projects/markdown/syntax

 

  1. Hello Michael,

    thanks for the helpful article. I put a link to it on my Simple-JNDI page on GitHub. Meanwhile I improved the introduction to Simple-JNDI. So I hope people will now have less problems to get it running.

    One note: the link blogs.oracle.com/randystuph/entry/injecting_jndi_datasources_for_junit does not work anymore.

    Best regards
    Holger