This post originated from an RSS feed registered with Agile Buzz
by Joe Walnes.
Original Post: Design by contract: testing implementations of interfaces
Feed Title: Joe's New Jelly
Feed URL: http://joe.truemesh.com/blog/index.rdf
Feed Description: The musings of a ThoughtWorker obsessed with Agile, XP, maintainability, Java, .NET, Ruby and OpenSource. Mmm'kay?
Here's a nice way of associating contracts with interfaces and testing the implementations conform.
A sample interface:
interface CheeseMaker {
int getCheeseCount();
void addCheese(Cheese cheese);
}
With the contracts:
there should be zero cheeses on creation.
adding a cheese should increment the count.
unless the cheese is a duplicate.
when adding a cheese, the cheese cannot be null.
You can create an abstract unit test for this interface that tests these contracts. The only thing it doesn't do is provide an implementation - instead it has an abstract factory method.
Now, every time you create an implementation of CheeseMaker, the test should extend CheeseMakerTest and you inherit the contract tests for free.
For example:
public class BigCheeseMaker implements CheeseMaker {
// ... ommited for sanity
}
public class BigCheeseMakerTest extends CheeseMakerTest {
// factory method implementation
protected CheeseMaker createCheeseMaker() {
return new BigCheeseMaker();
}
// ... any additional tests go here
}
It's important to note that this tests the contract but does not enforce them. It's very flexible and there are very few contracts (if any at all) that couldn't be expressed in a unit-test.
This helps defensive development with the added safety of unit-tests.
As a bonus, you can use TestDox to generate documentation for interfaces (much more useful than implementations), like so: