/ 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 technologist focusing on cloud-native technologies, DevOps, CI/CD pipelines, and system observability. His focus revolves around creating technical content, delivering talks, and engaging with developer communities to promote the adoption of modern software practices. With a strong background in software, he has worked extensively with the JVM, applying his expertise across various industries. In addition to his technical work, he is the author of several books and regularly shares insights through his blog and open-source contributions.

Read More
Speeding up your DBUnit tests with JavaDB
Share this