I am trying to set up some jUnit testing. Our database is connected by the server using JNDI. We have an xml describing the setup in root.xml. How do I set up jUnit to hook up to the database? I'd prefer to have it just read the the stuff off of root.xml, but I'm open to setting it up anyway that works.
-
You'll have to paste your root.xml file here, so potential answerers will know what kind of information they can be working with. Would you like your JUnit testers to run inside the server process, or as a standalone process? – Isaac Sep 22 '12 at 19:06
-
Are you using a dependency injection framework? – Kkkev Sep 23 '12 at 07:10
-
I don't have the root.xml now. It just has a couple database connections. – Joe Sep 23 '12 at 23:06
-
I am not using a dependency injection framework. – Joe Sep 23 '12 at 23:07
-
The root xml says this (basically):
-
See also http://stackoverflow.com/questions/5940895/how-to-test-a-mocked-jndi-datasource-with-spring – Vadzim Jul 05 '16 at 08:58
6 Answers
I've found this Blog: https://blogs.oracle.com/randystuph/entry/injecting_jndi_datasources_for_junit
About H2 Datasource: http://www.h2database.com/javadoc/org/h2/jdbcx/JdbcConnectionPool.html
So for my Code:
package com.example.test;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;
import org.h2.jdbcx.JdbcConnectionPool;
import junit.framework.TestCase;
public class JunitDataSource extends TestCase {
public void setUp() throws Exception {
// rcarver - setup the jndi context and the datasource
try {
// Create initial context
System.setProperty(Context.INITIAL_CONTEXT_FACTORY, "org.apache.naming.java.javaURLContextFactory");
System.setProperty(Context.URL_PKG_PREFIXES, "org.apache.naming");
InitialContext ic = new InitialContext();
ic.createSubcontext("java:");
ic.createSubcontext("java:/comp");
ic.createSubcontext("java:/comp/env");
ic.createSubcontext("java:/comp/env/jdbc");
JdbcConnectionPool ds = JdbcConnectionPool.create(
"jdbc:h2:file:src/main/resources/test.db;FILE_LOCK=NO;MVCC=TRUE;DB_CLOSE_ON_EXIT=TRUE", "sa", "sasasa");
// Construct DataSource
// OracleConnectionPoolDataSource ds = new
// OracleConnectionPoolDataSource();
// ds.setURL("jdbc:oracle:thin:@host:port:db");
// ds.setUser("MY_USER_NAME");
// ds.setPassword("MY_USER_PASSWORD");
ic.bind("java:/mydatasourcename", ds);
} catch (NamingException ex) {
Logger.getLogger(JunitDataSource.class.getName()).log(Level.SEVERE, null, ex);
}
}
public void testSimple() throws Exception {
// Obtain our environment naming context
Context initCtx = new InitialContext();
// Look up our datasource
DataSource ds = (DataSource) initCtx.lookup("java:/mydatasourcename");
Connection conn = ds.getConnection();
Statement stmt = conn.createStatement();
ResultSet rset = stmt.executeQuery("SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES");
while (rset.next()) {
System.out.println("<<<\t"+rset.getString("TABLE_NAME"));
}
}
}
Note: I had to add Tomcat Library and the jars inside the Tomcat's bin directory to get it working

- 609
- 1
- 5
- 21
-
I'm having the same issue, what changes should I make to run it on `MySQL` ? – marknorkin Feb 07 '15 at 11:42
-
1Just to help those that wonder where to find the jar containing org.apache.naming.java.javaURLContextFactory and assoc. -> Pick a recent TOMCAT server distribution, look for catalina.jar and tomcat-juli.jar, and add them to your classpath. You need too, of course, to add the database provider JDBC client jar to the classpath. – Bernard Hauzeur May 24 '17 at 16:47
I found that the best way to do it is to use something called Simple-Jndi.
I added this to the maven file:
<dependency>
<groupId>simple-jndi</groupId>
<artifactId>simple-jndi</artifactId>
<version>0.11.4.1</version>
<scope>test</scope>
</dependency>
You can download the the package here, the download contains an instruction manual. http://code.google.com/p/osjava/downloads/detail?name=simple-jndi-0.11.4.1.zip&can=2&q=
After adding to to your project you just have to add a couple of properties files, per the instructions.
However, after you add the dependency, I believe you can add your jndi resources programmatically instead of using properties files. You do something like this: (new InitialContext()).rebind("datasource",myDatasource);
-
Another guide on Simple-Jndi: http://fandry.blogspot.com.by/2011/03/junit-based-integration-testing-with.html – Vadzim Jul 05 '16 at 09:07
-
Neither of the guides above provide enough information to use simple-jndi. I've tried both, and the author's do not give enough detail for a first user to successfully use the library. (I've been trying for the past 2 days to make sense of their instructions). Are there any other resources which clearly explain how to use Simple-JNDI? – kiwicomb123 Mar 03 '17 at 05:42
-
1The above-named Simple-JNDI project is not under active development anymore. So I forked it, did some bug fixes and implemented some new features. I also rewrote the introduction to make it more understandable. Give it a try please. See https://github.com/h-thurow/Simple-JNDI – Holger Thurow Jun 25 '17 at 07:04
I have used Simple-JNDI for this purpose for years now. It gives you an in-memory implementation of a JNDI Service and allows you to populate the JNDI environment with objects defined in property files. There is also support for loading datasources or connection pools configured in a file.
To get a connection pool you have to create a file like this:
type=javax.sql.DataSource
driver=com.sybase.jdbc3.jdbc.SybDriver
pool=myDataSource
url=jdbc:sybase:Tds:servername:5000
user=user
password=password
In your application you can access the pool via
Context ctx = new InitialContext();
DataSource ds = (DataSource) ctx.lookup("path/to/your/connectionPool");
You can find more about it at https://github.com/h-thurow/Simple-JNDI.
TomcatJNDI helps with that situation too. It can process Tomcat’s configuration files and creates the same JNDI environment as Tomcat does, but without starting a server. So you can run classes with dependencies on Tomcat’s JNDI environment in e. g. JUnit tests.
TomcatJNDI tomcatJNDI = new TomcatJNDI();
tomcatJNDI.processContextXml(new File(“tomcat-root-dir/conf/context.xml”);
tomcatJNDI.start();
Then your classes can lookup the DataSource as when they would run in Tomcat.
More about TomcatJNDI can be found here: https://github.com/h-thurow/TomcatJNDI

- 764
- 4
- 12
Would you like to create datasource programmatically on Application Server? Referene :
If you already created on Sever,
public class YourTestCase {
private java.sql.Connection conn;
@BeforeClass
public static void init() {
/* Weblogic */
try {
Context ctx = null;
Hashtable ht = new Hashtable();
ht.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");
ht.put(Context.PROVIDER_URL, "t3://<your-host>:<your:post>");
ctx = new InitialContext(ht);
javax.sql.DataSource ds = (javax.sql.DataSource) ctx.lookup ("<your-datasource-jndi-name>");
conn = ds.getConnection();
} catch(Exception e) {
}
/* JBoss 5*/
Context.INITIAL_CONTEXT_FACTORY ---> org.jnp.interfaces.NamingContextFactory
Context.PROVIDER_URL ---->http://localhost:1099
}
@AfterClass
public static void finished() {
}
@Test
public void testMethod() {
try {
Statement stmt = conn.createStatement();
stmt.execute("select * from someTable");
ResultSet rs = stmt.getResultSet();
// do operation
stmt.close();
conn.close();
} catch (Exception e) {
// a failure occurred
} finally {
try {ctx.close();
} catch (Exception e) {
}
}
}
}
}

- 9,651
- 13
- 83
- 131
You can add Tomcat lib via maven dependency using below, to get it working.
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>catalina</artifactId>
<version>6.0.18</version>
<scope>test</scope>
</dependency>

- 49
- 6
I think you should try to mock out the database. Use appropriate framework, for example Mockito, it creates mocks and have DI abilities.

- 5,661
- 7
- 37
- 57
-
Will Mockito make JNDI data sources for me? I can't change around how the existing code works, because me boss would be very unhappy with that. – Joe Sep 23 '12 at 23:08