Some unfortunate behavior in DBUnit

Posted by Keith McMillan

July 7, 2009 | 1 Comment

Last week, I posted about our recent success at getting DBUnit working with an in-memory HSQLDB database,  which allows us to more thoroughly test data access objects (DAOs). Further work with that solution has unearthed some rather frustrating problems unfortunately.

Presume for a moment that we have a table, called “mytable” with just a few columns:

id - integer, not nullable
name - varchar, 50 characters, not nullable
description - varchar, 255 characters, nullable

An initial dataset in Unitils xml parlance could look like this:

<?xml version='1.0' encoding='UTF-8' ?>
    <mytable id="1" name="first"/>

All fine and good. Now, let’s add a second row with the description. When we do this, it seems that Unitils, or rather DBUnit, insists that we specify the null value for the first row.  The rule seems to be that you have to mention a column everywhere in order to use it anywhere. That’s ok, we can add in the null like this:

<?xml version='1.0' encoding='UTF-8' ?>
    <mytable id="1" name="first" description="[null]"/>
    <mytable id="2" name="second" description="description for second"/>

OK, so a little inconvenient, but not the end of the world by any means. Curiously, I was able to find some oblique references on the web that adding in the “[null]” shouldn’t be necessary with Unitils, but my experiences with Unitils version 2.3, which comes bundled with DBUnit 2.4.4, seems to contradict that. Now, however, let’s take a look at the expected dataset functionality.

The @ExpectedDataSet tag allows us to provide the same sort of XML file for Unitils to use after a unit test has run, in order to specify what we expect the “after” condition of the tables to be. The first step here would be to copy the resulting XML file, and use it as the expected dataset.  When we do that we immediately run in to a problem, and it’s that [null].

When we try to specify a column that has a null expected value, such as our description=”[null]” above, DBUnit throws a null pointer exception when it attempts to compare the value to the one in the database.  This is a known bug in Unitils 2.3, it seems, scheduled for fix in the next release.  What happens if we drop off the description in that first row, then?

When we drop off the null description in the first row, everything seems fine until we try to verify the description for the second row.  It doesn’t matter what we specify as the value for the description in this case, it won’t be checked.  It seems that just as in the input case, we have to mention a column everywhere if we’re going to use it anywhere, but now we have the additional complication that we can’t use [null] to specify a null value.  To make matters worse, the failure is silent, there’s no indication that it didn’t occur.

I’ve not tracked this down to say exactly where the problem lies yet, but since I was so glowing last week in my praise of these tools, I thought it only honest to make anyone reading that post aware of these problems too.  What can you do if you encounter this problem? The easiest thing to do is to verify your database contents programmatically, rather than via the @ExpectedDataSet tag, which is the way that the Unitils team suggest you do things anyway. It’s a less-than-satisfying solution, because it means for the typical update case, you update a single record, then are forced to re-read every row in order to make sure that none of the others changed, where the ExpectedDataSet tag seems tailor-made for that sort of thing.

I’ll be trying to dig further into this in order to submit a bug with either Unitils or DBUnit, but it might take a while since I’m not very familiar with their code structure, and deadlines for my client are deadlines that must be met first.

So it seems that bug UNI-148 is the culprit for this problem. The Unitils maintainers have fixed the bug in the upcoming 2.4 release, and were kind enough to provide an early build, which we’ve tried and it works.

With the fix, you do need to provide all the columns in for every row, which means you need to use “[null]" for any columns you don’t use in a particular row, but at least it works in Expected Data Sets now.


RSS feed | Trackback URI

1 Comment »

2009-10-13 20:45:29

[…] Some unfortunate behavior in DBUnit […]

Name (required)
E-mail (required - never shown publicly)
Your Comment (smaller size | larger size)
You may use <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> in your comment.