The Artima Developer Community
Sponsored Link

Agile Buzz Forum
Design by contract: testing implementations of interfaces

0 replies on 1 page.

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 0 replies on 1 page
Joe Walnes

Posts: 151
Nickname: jwalnes1
Registered: Aug, 2003

Joe Walnes, "The Developers' Coach" from ThoughtWorks
Design by contract: testing implementations of interfaces Posted: Aug 1, 2003 2:54 PM
Reply to this message Reply

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?
Latest Agile Buzz Posts
Latest Agile Buzz Posts by Joe Walnes
Latest Posts From Joe's New Jelly

Advertisement

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.

public abstract class CheeseMakerTest extends TestCase {

    // abstract factory method
    protected abstract CheeseMaker createCheeseMaker(); 

    public void testZeroCheesesOnCreation() {
        CheeseMaker cheeseMaker = createCheeseMaker();
        assertEquals(0, cheeseMaker.getCheeseCount());
    }

    public void testAddingACheeseIncrementsCount() {
        CheeseMaker cheeseMaker = createCheeseMaker();
        cheeseMaker.addCheese(new Cheese("Cheddar"));
        cheeseMaker.addCheese(new Cheese("Wensleydale"));
        assertEquals(2, cheeseMaker.getCheeseCount());
    }

    public void testDuplicateCheesesDoNotIncrementCount() {
        CheeseMaker cheeseMaker = createCheeseMaker();
        cheeseMaker.addCheese(new Cheese("Cheddar"));
        cheeseMaker.addCheese(new Cheese("Cheddar"));
        assertEquals(1, cheeseMaker.getCheeseCount());
    }

    public void testNullCheeseCausesIllegalArgumentException() {
        CheeseMaker cheeseMaker = createCheeseMaker();
        try {
            cheeseMaker.addCheese(null);
            fail("expected exception");
        } catch (IllegalArgumentException e) {} // good
    }

}

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:

CheeseMaker

  • Zero cheeses on creation.
  • Adding a cheese increments count.
  • Duplicate cheeses do not increment count.
  • Null cheese causes illegal argument exception.

Read: Design by contract: testing implementations of interfaces

Topic: The convention I wish I was at Previous Topic   Next Topic Topic: Been working on the blog tools

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use