I like DBUnit. Well, I dislike using it, but that’s because I dislike writing persistence tests. I’d hate them a lot more without it.
I like it not only because it turns a dreaded chore into a mildly unpleasant one, but for how easy it is to extend and modify. Virtually everything in DBUnit, at least everything you might need to customise, is designed in what I think of as the Spring style: a combination of interfaces, abstract implementations and concrete implementations. The method and constructor parameters expect and return interfaces, so you can plug in any implementation you like, including your own. If you do want to implement your own version, there’s an abstract base class providing basic common features that you can rely on. And to make it easy to get started, there are already concrete implementations covering at least 95% of potential use cases. These help you in two ways: you can use them off-the-shelf and they just work, and when you need, you can model your own implementations on them.
The danger with the Spring style is that defining everything in terms of interfaces makes it, paradoxically, difficult to learn at first. I had that problem with Spring Batch. It’s so modular that you’re never quite sure how it all fits together. The docs perpetuate this implementation-agnostic confusion: each component’s interactions are described abstractly, because the author doesn’t know which implementation you will really choose to supply. I don’t have a problem with abstraction, but I need to start from concrete examples. After you’ve built your first batch, you have your marks, you have a nominal case in mind and everything is just variations on that. But at the beginning, it’s confusing.
DBUnit doesn’t have that problem, perhaps because the number of potential use cases is far smaller, but I think also because the documentation takes, as its starting point, a nominal case using concrete classes, and then describes variants thereof.
DBUnit isn’t perfect by any means. Not everyone finds it as easy to use as they’d like (take that infuriating issue with resolving DTDs, for instance), and there’s some pretty crufty code in its entrails, if you go digging. But I like it all the better for that. When I look at the source code of most Spring components, I could never imagine writing something that myself. When I read DBUnit’s source code, I’m more likely to think, “Hey, I could write something like that.” For that reason, DBUnit makes a better ambassador for the Spring style than does Spring itself. It shows that you don’t need to be a magician to write a useful and extensible component. You just need to care.