XML is the legacy way to inject dependencies, but is still in use. Consider the following monolithic XML configuration file:

<?xml version="1.0" encoding="UTF-8"?> <beans xmlns= "http://www.springframework.org/schema/beans" xmlns:jee= "http://www.springframework.org/schema/jee" 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.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd" > <jee:jndi-lookup id= "dataSource" jndi-name= "jdbc/MyDataSource" /> <bean id= "productRepository" class= "ProductRepository" > <constructor-arg ref= "dataSource" /> </bean> <bean id= "customerRepository" class= "CustomerRepository" > <constructor-arg ref= "dataSource" /> </bean> <bean id= "orderRepository" class= "OrderRepository" > <constructor-arg ref= "dataSource" /> </bean> <bean id= "orderService" class= "OrderService" > <constructor-arg ref= "productRepository" index= "0" /> <constructor-arg ref= "customerRepository" index= "1" /> <constructor-arg ref= "orderRepository" index= "2" /> </bean> </beans>

At this point, Integration Testing orderService is not easy as it should be. In particular, we need to:

Download the application server

Configure the server for the jdbc/MyDataSource data source

Deploy all classes to the server

Start the server

Stop the server After the test(s)

Of course, all previous tasks have to be automated! Though not impossible thanks to tools such as Arquillian, it’s contrary to the KISS principle. To overcome this problem and make our life (as well as test maintenance) easier in the process requires tooling and design. On the tooling part, we’ll be using a local database. Usually, such a database is of the in-memory kind e.g. H2. On the design part, his requires separating our beans by creating two different configuration fragments, one solely dedicated to the data source to be faked and the other one for the beans constituting the SUT.

Then, we’ll use a Maven classpath trick: Maven puts the test classpath in front of the main classpath when executing tests. This way, files found in the test classpath will "override" similarly-named files in the main classpath. Let’s create two configuration files fragments:

The "real" JNDI datasource as in the monolithic configuration <beans...> <jee:jndi-lookup id= "dataSource" jndi-name= "jdbc/MyDataSource" /> </beans>

The Fake datasource <beans...> <bean id= "dataSource" class= "org.apache.tomcat.jdbc.pool.DataSource" > <property name= "driverClassName" value= "org.h2.Driver" /> <property name= "url" value= "jdbc:h2:~/test" /> <property name= "username" value= "sa" /> <property name= "maxActive" value= "1" /> </bean> </beans>

Note we are using a Tomcat datasource object, this requires the org.apache.tomcat:tomcat-jdbc:jar library on the test classpath. Also note the maxActive property. This reflects the maximum number of connections to the database. It is advised to always set it to 1 for test scenarios so that connections pool exhaustion bugs can be checked as early as possible.

The final layout is the following:

JNDI datasource Other beans Fake datasource

The final main-config.xml file looks like:

<?xml version="1.0" encoding="UTF-8"?> <beans...> <import resource= "classpath:datasource-config.xml" /> <!-- other beans go here --> </beans>