/ DBUNIT, DERBY, JAVADB, UNIT TEST

Speeding up your DBUnit tests with JavaDB

Introduction to DBUnit

With the developed use of JUnit, many additions were made to it. These additions take advantage of the pluggable nature of JUnit. One of these contribution is DBUnit. DBUnit enables your unit tests to:

  • preload the database with datas pertaining to your current test only,
  • run your unit test (as usual),
  • remove the data you preloaded in order to put the database in the same it was before your additions.

In effect, you can now test your DAO classes. Let’s take a (very) simple example: a PersonDao class that manipulates Person objects.

You create a test case that extends org.dbunit.JdbcBasedDBTestCase. It forces you to implement the following methods:

  • IDataSet getDataSet() throws Exception where IDataSet represents a collection of tables,
  • String getConnectionUrl() that returns the connection url of the database,
  • String getDriverClass() that returns the class name of the driver used for database access.

This process enables you to test your DAO classes with various data sets. Moreover, these data sets can be initialized from various sources: I recently discovered one of these sources could be an Excel file! Not very open-source, I agree, but very much more manageable than those cumbersome XML files.

Yet, these tests are usually made on remote and shared databases. Drawbacks include:

  1. a sheer performance cost: remote databases use networks and, as such, increase the time to get the result, even if the databases themselves are very performant on their own,
  2. a risk of using the wrong datas: if using a shared database, you are taking chances that the data you want to use for your test has just been modified by another developer. If your DB uses a schema for each developer, well, that’s just configuration overhead…​

The first point is a good way for developers not to write DB tests, since they can’t complete the build fast enough. The second point paves the road for correct tests to fail or more importantly, for incorrect tests to succeed. Both are bad.

Using an alternate local DB

The answer to these problems are the use of an alternate local DB. Yet, this solution has its own disadvantages including: license costs, configuration overhead for each developer’s machine and the ever-popular "It doesn’t work on my computer". Well, let’s get back to the shared BD ? Clearly no: there’s a often overlloked option.

Apache Derby logo

Since version 6 of the JVM, Sun ships an embedded database with its JDK. This DB, called oh-so-originally JavaDB, is a reuse of the not-so-old Apache Derby database project. Apache Derby, is an open source relational database implemented entirely in Java.

Main advantages are:

  • a small memory footprint,
  • the main SQL-99 Core / SQL-2003 mandatory features (see table for unsupported features),
  • an embedded driver.

Quick how-to

First of all, you should provide a mechanism to provide a connection in different ways, for example with dependency injection, probably the method you will choose for a real-world project (be it with Spring or Guice). For my proof-of-concept, I chose the method-overloading mechanism to keep it simple (KISS without the trailing S).

Then, it’s all very simple:

  • the getConnectionUrl() should return "java:derby:[your_chosen_db_name];create=true",
  • the getDriverClass() should return "org.apache.derby.jdbc.EmbeddedDriver",
  • the getDataSet() should return very simply getConnection().createDataSet().

Et voilà !

The Maven artifact that contains an example is just here: JavaDB example sources

Conclusion

The use of JavaDB is not the golden hammer to your DB tests problems. According to me, there’s much to be done in order for it to be really full-SQL compliant. Yet, 90% of the common SQL requests used troughout prjects can be parsed by it. There’s even an Hibernate dialect available. In conclusion, it can save much anguish and much time for developers. So, why don’t use it ?

Nicolas Fränkel

Nicolas Fränkel

Nicolas Fränkel is a Developer Advocate with 15+ years experience consulting for many different customers, in a wide range of contexts (such as telecoms, banking, insurances, large retail and public sector). Usually working on Java/Java EE and Spring technologies, but with focused interests like Rich Internet Applications, Testing, CI/CD and DevOps. Currently working for Hazelcast. Also double as a teacher in universities and higher education schools, a trainer and triples as a book author.

Read More