How to test a mocked JNDI datasource with Spring? How to test a mocked JNDI datasource with Spring? spring spring

How to test a mocked JNDI datasource with Spring?


You can use SimpleNamingContextBuilder to make a jndi datasource available to your tests:

    SimpleNamingContextBuilder builder = new SimpleNamingContextBuilder();    builder.bind("java:comp/env/jdbc/mydatasource", dataSource);    builder.activate();

https://fisheye.springsource.org/browse/spring-framework/spring-test/src/main/java/org/springframework/mock/jndi/SimpleNamingContextBuilder.java?hb=true

This isn't exactly mocking the datasource, but it does make the datasource available via jndi for your tests.


I usually define my JNDI dependencies in seperate file, like datasource-context.xml:

<beans xmlns="http://www.springframework.org/schema/beans"    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xmlns:jee="http://www.springframework.org/schema/jee"    xmlns:p="http://www.springframework.org/schema/p"    xsi:schemaLocation="        http://www.springframework.org/schema/beans         http://www.springframework.org/schema/beans/spring-beans-3.0.xsd        http://www.springframework.org/schema/jee        http://www.springframework.org/schema/jee/spring-jee-3.0.xsd">    <jee:jndi-lookup id="dataSource"         jndi-name="java:comp/env/dataSource"         expected-type="javax.sql.DataSource" /></beans>

So that in test resources I can create another file and define the test datasource however it suits me, like datasource-testcontext.xml:

<beans xmlns="http://www.springframework.org/schema/beans"    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xmlns:p="http://www.springframework.org/schema/p"    xsi:schemaLocation="        http://www.springframework.org/schema/beans         http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">    <bean id="dataSource"        class="org.springframework.jdbc.datasource.DriverManagerDataSource"        p:driverClassName="org.hsqldb.jdbcDriver"        p:url="jdbc:hsqldb:hsql://localhost:9001"        p:username="sa"        p:password="" /> </beans>

And then in my test class I use the test configuration of the datasource instead of production one that depends on JNDI:

@ContextConfiguration({    "classpath*:META-INF/spring/datasource-testcontext.xml",    "classpath*:META-INF/spring/session-factory-context.xml"})public class MyTest {}

If the data source is not defined in a separate file You can still stub the object returned by JNDI calls easily:


You can create your own mock DataSource by extending Spring's AbstractDataSource.

import java.sql.Connection;import java.sql.SQLException;import org.springframework.jdbc.datasource.AbstractDataSource;/** * Mock implementation of DataSource suitable for use in testing. *  * */public class MockDataSource extends AbstractDataSource {    private Connection connection;    /**     * Sets the connection returned by javax.sql.DataSource#getConnection()     * and javax.sql.DataSource#getConnection(java.lang.String, java.lang.String)     *      * @param connection     */    public void setConnection(Connection connection) {        this.connection = connection;    }    /*     * (non-Javadoc)     * @see javax.sql.DataSource#getConnection()     */    public Connection getConnection()            throws SQLException {        return connection;    }    /*     * (non-Javadoc)     * @see javax.sql.DataSource#getConnection(java.lang.String, java.lang.String)     */    public Connection getConnection(String username, String password)            throws SQLException {        return connection;    }}

I'd separate the JNDI lookup of the connection from the rest of the code. Inject the DataSource into your Data Access Objects (DAOs) and use the MockDataSource for testing the DAOs.