Specifying Different Databases for Unit and System Testing
Quality software requires thorough testing. Most applications today also utilize databases for persistent storage. As such, being able to test your application against your target database is important, be it unit testing, functional testing, or system testing.
One of the key points in unit testing code that performs database operations is that the database must always be in a known state before the test is run. This usually requires removing all data and inserting the necessary data pre-conditions. Fortunately, there are tools that would facilitate this type of testing (e.g. DBUnit).
Unfortunately, the approach above produces a simple, yet annoying problem. Since the unit tests will use the default database configuration, it will utilize the same database as when you deploy the application to do some system testing. What if you were debugging some UI bug and have already added some sample test data to the database? Running the unit test would remove all the data. Pretty annoying if you asked me.
I will present here a simple technique to solve this problem that utilizes Spring Framework and Maven.
The first step is to transfer the database configuration to a properties file. Here’s the spring xml configuration to do that:
And here’s the spring.properties file.
jdbc.url=jdbc:mysql://localhost/prod
jdbc.username=root
jdbc.password=root
The key items to note are:
- Configure the JPA persistence manager (spring bean = persistenceUnitManager) to utilize an external data source (Note: Don’t forget to also remove any data source configurations in your persistence.xml file).
- Add the PropertyPlaceholderConfigurer bean to enable you to configure the bean properties via a properties file.
- Set the systemPropertiesModeName to SYSTEM_PROPERTIES_MODE_OVERRIDE. This will enable system defined properties to override those defined in the properties file.
- Configure your data source to utilize the properties defined in your properties file.
So now you are able to configure your data source to use a properties file and is by default utilizing the production database. To configure it to utilize a different database when running unit tests, configure the maven-surefire-plugin to pass a different database URL via the system properties. Here’s a quick snippet:
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<useFile>true</useFile>
<forkMode>once</forkMode>
<childDelegation>false</childDelegation>
<argLine>-Xmx512M</argLine>
<workingDirectory>${basedir}</workingDirectory>
<systemProperties>
<property>
<name>log4j.configuration</name>
<value>log4j-tests.properties</value>
</property>
<property>
<name>jdbc.driverClassName</name>
<value>com.mysql.jdbc.Driver</value>
</property>
<property>
<name>jdbc.url</name>
<value>jdbc:mysql://localhost/unit_test</value>
</property>
<property>
<name>jdbc.username</name>
<value>root</value>
</property>
<property>
<name>jdbc.password</name>
<value>root</value>
</property>
</systemProperties>
</configuration>
</plugin>
With this, every time you run the unit test cases, it will use the unit_test database, and when you deploy the application to do system testing, it will use the prod database.
- BROWSE / IN TIMELINE
- « Reusing JPA models using embedded entities and composition
- BROWSE / IN Java ORM Testing
- « Reusing JPA models using embedded entities and composition
SPEAK / ADD YOUR COMMENT
Comments are moderated.

