DbUnit

I’ve decided to revisit the JUnit testing Hibernate and Spring recipe that I posted a while back. A problem with the previous recipe is that it did not provide any means to initialize the test database. This wasn’t too much of a problem as I was mostly testing the data insert operations of the DAOs. I then used the same DAO to retrieve the newly inserted data and tested what came back. However this is no good if I don’t want insert operations on my DAO (if it’s to retrieve read only data from the database) or if I want to test the retrieval operations independently of the insert operations.

This post extends the recipe to include a means of initialising the database using DbUnit.

In its own words:

DbUnit is a JUnit extension (also usable with Ant) targeted at database-driven projects that, among other things, puts your database into a known state between test runs.

In addition, I’ve upgraded my test class to use JUnit 4 style annotations rather than extending (a subclass of) TestCase as was required in JUnit 3.

JUnit 4 and Spring TestContext Framework

The Spring TestContext Framework introduced in Spring 2.5 provides an annotation based alternative to the clunky AbstractSingleSpringContextTests class available in Spring 2.0. It can be used by subclassing one of the JUnit 3 / JUnit 4 / TestNG abstract support classes. In the case of JUnit 4.4 it can also be used within a custom JUnit Runner eliminating the need for your test class to subclass anything.

Using either of these methods, your Spring context can be specified using the @ContextConfiguration annotation. I’ve used the custom JUnit Runner so my class definition looks like this:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {
    "classpath:spring-hibernate.xml", // Containing Hibernate session bean, transaction config and DAOs
    "classpath:spring-test-dataSources.xml" // Containing HyperSQL datasource and test Hibernate properties
})
public class SpannersTest {

With this minimal preamble in place I can now inject my Spring beans directly into instance variables using the @Autowired annotation:

    @Qualifier("spannersDAO")
    @Autowired protected SpannersDAO spannersDAO; // Injected by springy magic
    @Autowired protected DataSource ds; // Injected by springy magic

Note that I use @Qualifier to specify the name of my DAO as I have two beans in my Context with type SpannersDAO.

DbUnit setUp and tests

DbUnit provides a good quick Getting Started guide. It can either be configured by subclassing DBTestCase (which itself is a subclass of JUnit 3 TestCase) or by using an instance of IDatabaseTester. As I’ve opted to follow a JUnit 4 annotation based style, I don’t want to subclass TestCase so I create my own instance of IDatabaseTester. In my case I want to create a DatabaseTester from a DataSource (which I’ve already injected via Springy magic) so I use the DataSourceDatabaseTester. In my setUp method I want to instantiate the DatabaseTester, provide it with a data set to insert into my database and then tell it to initialize my database by calling onSetup():

@Before
public void setUp() throws Exception {
    dbTester = new DataSourceDatabaseTester(ds);

    IDataSet dataSet = new FlatXmlDataSet(getClass().getResource("SpannersTest.xml"));
    dbTester.setDataSet(dataSet);
    dbTester.onSetup();
}

The pre-populated database can now be queried via the DAOs:

@Test
public void testGet() {
    Spanner spanner = spannersDAO.get(1);
    assertNotNull(spanner);
    assertEquals("Hazell", spanner.getName())
}

Source

Download source of this demo

This demo is available as a zip file. After unzipping, the test can be run using Maven 2:

mvn test

Leave a Reply

Your email address will not be published. Required fields are marked *