Tuesday, June 23, 2009

Testing an interface in JUnit4

How do you test an interface? Obviously, there is no way to instantiate it directly, so you have to write a test for each different implementation. I feel shivers down my spine even as I write it... that awfully smells like duplication, which - should you ask - is bad. Nevertheless, I'd like to test every possible implementation.

As JUnit Recipes reports, this is quite simple:
  1. Start from the test case for one of the implementation (I assume you have them, don't you?)
  2. Create a new abstract test case in which you will define the expected behavior
  3. Have your test case extend the abstract test case
  4. Move the code that instantiates the object under test into a separate method, storing the object as a reference to the interface and not the implementation.
  5. Adjust the rest of the code referring to the interface behavior accordingly
  6. Create an abstract creation method for each concrete creation method
  7. Move all tests for the interface to the abstract test case
At this point in the test cases for the implementations there should be only implementation specific behavior, not related to the interface.

I tried it all in JUnit 4... and it didn't work, as when I ran the tests for all the project I got a wonderful java.lang.InstantiationException (actually several of them) for the abstract test case.

After some personal tries and a bit of googling I found that all I needed to do to have everything run smoothly was to add the @Ignore assertion to the abstract test case. Now we have no excuses!

No comments: