Thursday, November 13, 2008

Testing Interface Implementations

I've been working on some library code recently, and working on a few implementations of an interface. I wrote and tested my first implementation, then started on the second one. I didn't think about it in advance but of course about 90% of the tests needed to be the same. I realized I needed to verify that every implementation adhered to the API spec I laid out.

I ended up moving all the shared "API" tests into an abstract base class, with one abstract method, create(). So far so good, it feels a little weird to have an abstract class doing testing, but it's also kind of cool. Instead of having Javadoc describing your API there is a clean set of tests that you can look at. Also if you want to implement the interface, now not only do you have access to the minimum set of behavioral requirements but, it's also easy to run the tests against your implementation.

I wish every API I had to implement had a hard contract of tests that I had to pass, that would make life so much easier.

Javadoc = soft contract
Tests = hard contract


Eric said...

Excellent stuff. I certainly love the "DRY"ness of it. As long as JUnit supports running tests in the super class using the implementation you assign (do you do this in the constructor or something?) in the subclass, I see nothing wrong with it. In fact, I can think of nothing better than what you've done. Damn you for making me say that.

zdsbs said...

it's possible there are some Junit wrinkles I don't know about, but if you have:

public class BarTest extends FooTest

and run BarTest in Junit, you'll execute and tests in FooTest as well

Web Statistics