8

I am toying a bit with Spring testing framework, but I have one problem. Normally when application is deployed on Tomcat we have

<Resource
       name="jdbc/sqliteDS"
       auth="Container"
       type="javax.sql.DataSource"
       maxActive="4"
       maxIdle="2"
       username="x"
       maxWait="5000"
       driverClassName="org.sqlite.JDBC"
       password="x"
       url="jdbc:sqlite:/home/xxx/db.sqlite"/> 

</Context>

in Tomcat context.xml,

<resource-ref>
    <description>sqlite DataSource</description>
    <res-ref-name>jdbc/sqliteDS</res-ref-name>
    <res-type>javax.sql.DataSource</res-type>
    <res-auth>Container</res-auth>
</resource-ref>

in web.xml and

<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
    <property name="jndiName" value="java:/comp/env/jdbc/sqliteDS" />
</bean>

in data-context.xml for getting data source, but how can I emulate JNDI resource for Spring test framework, because now during the initialization I am getting errors that data source is not found, and he is right.

Also, it would be great if one can do that without writing another .xml file.

Andna
  • 6,539
  • 13
  • 71
  • 120
  • See this http://stackoverflow.com/questions/5940895/how-to-test-a-mocked-jndi-datasource-with-spring/29887209#29887209 – Mohit Apr 27 '15 at 04:30

1 Answers1

9

I had to deal with this question a while ago, and I didn't find a suitable solution, but a workaroud which implies another xml file :

First you create a Spring configuration file defining your JNDI infos (jndi.xml) :

<beans
  xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

  <bean id="dataSource" class="org.apache.tomcat.dbcp.dbcp.BasicDataSource" destroy-method="close">
    <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
    <property name="url" value="jdbc:oracle:thin:@server:port:instance" />
    <property name="username" value="user" />
    <property name="password" value="pwd" />
  </bean>
</beans>

Then a static class to bind your JNDI variable :

public class Initialize {
    public static void initializeJndi() throws Exception {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("jndi.xml");
        SimpleNamingContextBuilder builder = new SimpleNamingContextBuilder();
        builder.bind("java:comp/env/jdbc/foo", applicationContext.getBean("dataSource"));
        builder.activate();
    }
}

Then in your test class, you add the following :

    @BeforeClass
    public static void initJndi() throws Exception {
        Initialize.initializeJndi();
    }

So that when you load your Spring main configuration file, the JNDI resource is accessible.

Maybe this is not the best way to do it but it surely works.

By the way, having a specific configuration file seems to be a good idea because you may not want to run your unit test on the final database. Doing so is more considered as integration testing than unit testing.

Hope it helps,

Mouwah

mouwah
  • 166
  • 4
  • Firstly, thanks for response. About the unit/integration testing, I wanted to write a test for a class that uses Spring container to look for annotated classes and so on, so I needed to load all the contexts, and to do so I need data source. – Andna Aug 21 '12 at 18:00