Unit Testing Spring-Hibernate Code with HSQLDB

Aug 6th, 2013 | By | Category: code snippets, design, j2ee, java

unit testRecently, we used hibernate extensively in a Spring based  Java application to connect to an Oracle DB. For unit testing, we decided that we should connect to HSQLDB so we can test out the usage of hibernate in a more portable manner. I scoured the web for snippets of code to achieve this. Finally, I decided that the best way to achieve this is to write a few classes that do most of this work in a transparent way and demand minimal changes from the test class. I am posting the code here since I think it would be useful for an extended audience.

Let us say, I need to write a test class called TestFoo.java in the package com.itmusings.test. The following are the support classes required.

First, I extended the Spring GenericXmlContextLoader to make it support the following:

  • It looks for the TestFoo.xml in the com.itmusings.test package. This is pretty much out of the box with the spring xml context loader.
  • It automatically loads the spring property configurator and looks for a file called TestFoo.properties in the com.itmusings.test package.
  • Thirdly, it looks for an annotation called DaoTest for the TestFoo class. If the class has that annotation, then it loads the Hibernate configuration via a file called init-hsqldb.xml 

Here is the code for the new EnhancedContextLoader that I came up with. This loader would have to be used in lieu of the default context loader that ships with Spring. See the test class below to see how we can configure it.

Next, I wrote a simple marker annotation (DaoTest) to denote the unit test class as a Dao Test class so that the HSQLDB configuration is only loaded for classes that require it.

Next, I wrote a file called init-hsql.xml that has the required spring and HSQLDB configuration. This configuration assumes the following:

  • The Spring Hibernate transaction manager would be called “transactionManager” by convention. This would be available for classes that need it. Hibernate session factory is called “sessionFactory”. A spring transaction template is also created for those who need it. All these beans would be useful for creating the DAOs required though all the beans may not be needed. 
  • This file allows the test class to parametrize a scripting file (called script.file). This file will contain DML statements that would create the necessary data for testing purposes. 
  • This file also allows the test class to parametrize the mapping files (.hbm.xml files) that need to be read for completing the test. The test would need only a subset of mapping files for testing.

Finally, I now need to write the test class that exercises this small framework that has thus been created. This class would have to do the following: 

  1. Use the extended context loader above.
  2. Mark itself as a DAO test class. ( by using the annotation above)
  3. Create its dependencies so that they can be automatically injected into the test class. 
  4. Initialize the parameters mapping.resources and script.file that have been mentioned above.

Here is a snippet of code.

 

  1. @RunWith(SpringJUnit4ClassRunner.class)
  2. @ContextConfiguration(loader=EnhancedContextLoader.class) /* use the enhanced context loader */
  3. @TransactionConfiguration(transactionManager="transactionManager", defaultRollback=false) /* use the name of the transaction manager */
  4. @DaoTest /* mark is as a DAO test */
  5. public class Test1 {
  6.         @Autowired /* ensure all DAOs are auto wired.
  7.         private FooDAO fooDAO;
  8.         // continue with the rest of the class.
  9.  
  10.  

Next write a spring file where you create the dependent DAO beans like FooDAO in this example. This bean would be auto wired into the test class.

Finally, write a properties file that initializes the two parameters. Call the file TestFoo.properties and keep it in the same package. In this case the file may look like

mapping.resources=Foo.hbm.xml, 
script.file=test-data.sql

Finally, write a test-data.sql that may have a few insert statements inside.

By executing this as a JUnit, we would now automatically initialize the HSQL database, create the schema from the hbm file, initialize the data from test-data.sql and be ready to execute tests!

Be Sociable, Share!

 Raja has been blogging in this forum since 2006. He loves a technical discussion any day. He finds life incomplete without a handy whiteboard and a marker.


Tags: , ,

Leave Comment