DbUnit with JUnit 4 - No Fluff Just Stuff

DbUnit with JUnit 4

Posted by: Paul Duvall on July 23, 2006

With the release of JUnit 4, the fundamental structure of a JUnit test has changed dramatically. The previously rigid rules which stipulated that all test method names must start with test and that fixtures be implemented by overriding setUp and tearDown are gone in favor of annotations, much like TestNG or .NET’s NUnit. This structural change, however, does not necessarily affect extension frameworks like DbUnit, XMLUnit, or HttpUnit to name a few.

If a framework was designed with a delegation API, then things will work smoothly. For example, take DbUnit, which was eloquently designed with an API which facilitates creating database aware tests without having to subclass a specialized test case. Using the latest version of DbUnit in JUnit 4, which, by the way, was created long before JUnit 4, is as simple as defining a static method decorated with the @BeforeClass or @Before annotation which handles fixture logic (such as inserting data into a database).

Remembering that DbUnit requires two things to work correctly (a database connection and a seed file), one can define a working JUnit 4 test case which utilizes DbUnit as follows:

@BeforeClass
public static void setUpBeforeClass() throws Exception {
 final ApplicationContext context =
  new ClassPathXmlApplicationContext("spring-config.xml");
 dao = (WordDAO) context.getBean("wordDAO");
 handleSetUpOperation();
}

This fixture is run just once and does three things. First, Spring is initialized, second, a reference to a DAO is obtained from Spring and finally, DbUnit is invoked via the handleSetUpOperation method which obtains a connection to a database and inserts the desired data via the connection as follows:

private static void handleSetUpOperation() throws Exception{
 final IDatabaseConnection conn = getConnection();
 final IDataSet data = getDataSet();
 try{
  DatabaseOperation.CLEAN_INSERT.execute(conn, data);
 }finally{
  conn.close();
 }
}

private static IDataSet getDataSet() throws IOException,
 DataSetException {
  return new FlatXmlDataSet(new File("test/conf/words-seed.xml"));
}

private static IDatabaseConnection getConnection()
 throws ClassNotFoundException, SQLException {
  Class.forName("org.gjt.mm.mysql.Driver");
  return new DatabaseConnection(DriverManager.
    getConnection("jdbc:mysql://localhost/words",
      "words", "words"));
}

Tests can now easily be defined with the @Test annotation.

@Test
public void findWord() throws Exception{
 IWord wrd = dao.findWord("pugnacious");
 Set defs = wrd.getDefinitions();
 assertEquals("size should be one", 1, defs.size());
}

@Test
public void createWord() {
 IWord word = new Word();
 word.setSpelling("pabulum");
 word.setPartOfSpeech(PartOfSpeechEnum.NOUN.getPartOfSpeech());
 Set definitions = this.getDefinitionsForWord(word);
 word.setDefinitions(definitions);
 try{
  dao.createWord(word);
 }catch(CreateException e){
  fail("CreateException thrown while trying to create a word");
 }
}  

This class doesn’t extend DbUnit’s specialized test case either. One thing to note, however: in order to use a coarsely grained fixture via the @BeforeClass annotation, you must declare the fixture method as static, which means using static class members if they are to be used in concert with fixture logic, such as my dao instance from above. This is in stark contrast to TestNG which is more flexible and doesn’t demand the static declaration.

If a JUnit extension framework predates the 4.0 release, it doesn’t necessarily mean the framework doesn’t work with 4.0. In fact, any framework should work and those that provide an API are in excellent shape to provide maximum flexibility.

For more information on JUnit 4 see IBM’s developerWork’s An early look at JUnit 4.

Paul Duvall

About Paul Duvall

Paul M. Duvall is the CEO of Stelligent, a consulting firm that helps clients create production-ready software every day. He has worked in virtually every role on software projects: developer, project manager, architect and tester. He's been a featured speaker at many leading software conferences. He is the principal author of Continuous Integration: Improving Software Quality and Reducing Risk (Addison-Wesley, 2007; Jolt 2008 Award Winner). He contributed to the UML 2 Toolkit (Wiley, 2003), authors a series for IBM developerWorks called Automation for the people and authored a chapter in the No Fluff Just Stuff Anthology: The 2007 Edition (Pragmatic Programmers, 2007). He is passionate about automating software development and release processes. He actively blogs on IntegrateButton.com

Why Attend the NFJS Tour?

  • » Cutting-Edge Technologies
  • » Agile Practices
  • » Peer Exchange

Current Topics:

  • Languages on the JVM: Scala, Groovy, Clojure
  • Enterprise Java
  • Core Java, Java 8
  • Agility
  • Testing: Geb, Spock, Easyb
  • REST
  • NoSQL: MongoDB, Cassandra
  • Hadoop
  • Spring 4
  • Cloud
  • Automation Tools: Gradle, Git, Jenkins, Sonar
  • HTML5, CSS3, AngularJS, jQuery, Usability
  • Mobile Apps - iPhone and Android
  • More...
Learn More »