From JUnit to SpringUnit Tests

A Brute Force JUnit Test

Previous Next
We begin by writing a typical JUnit test of the constructor for CompositeDate. January 1 and December 31 are obvious boundary cases. For each test, we introduce input values for year, month and day, and expected values again for each of those. We call the constructor with with inputs and check that the fields of the constructed object match our expectations.
package org.springunit.examples.constructor.junit.v1;

public class CompositeDateConstructorTest extends TestCase {

    public void testJan01() throws Exception {
        int day = 1;
        int month = 1;
        int year = 2006;
        int expectedDay = 1;
        int expectedMonth = 1;
        int expectedYear = 2006;
        CompositeDate subject = new CompositeDate(year, month, day);
        assertTrue(expectedMonth == subject.getMonth());
        assertTrue(expectedDay == subject.getDay());
        assertTrue(expectedYear == subject.getYear());
    }

    public void testDec31() throws Exception {
        int day = 31;
        int month = 12;
        int year = 2006;
        int expectedDay = 31;
        int expectedMonth = 12;
        int expectedYear = 2006;
        CompositeDate subject = new CompositeDate(year, month, day);
        assertTrue(expectedMonth == subject.getMonth());
        assertTrue(expectedDay == subject.getDay());
        assertTrue(expectedYear == subject.getYear());
    }

}
Next we add tests for valid leap days. The first checks for the sort that happens every four years; the second checks those that occur once every four hundred. (Three of every four centuries are not leap years, an exception to the rule that every fourth year is a leap year.)
    public void testFeb29Leap2004() throws Exception {
        int day = 29;
        int month = 2;
        int year = 2004;
        int expectedDay = 29;
        int expectedMonth = 2;
        int expectedYear = 2004;
        CompositeDate subject = new CompositeDate(year, month, day);
        assertTrue(expectedMonth == subject.getMonth());
        assertTrue(expectedDay == subject.getDay());
        assertTrue(expectedYear == subject.getYear());
    }
	
    public void testFeb29Leap2000() throws Exception {
        int day = 29;
        int month = 2;
        int year = 2000;
        int expectedDay = 29;
        int expectedMonth = 2;
        int expectedYear = 2000;
        CompositeDate subject = new CompositeDate(year, month, day);
        assertTrue(expectedMonth == subject.getMonth());
        assertTrue(expectedDay == subject.getDay());
        assertTrue(expectedYear == subject.getYear());
    }
Four months have 30 days; the test for April is representative. For the date April 31, an InvalidDateException should be thrown: that is the expected result. For this kind of test, where the throwing of an exception is the expected behavior, this is a common pattern. A try-catch block surrounds the call to the method(s) being tested, and a test failure is declared if calling the method fails to throw an exception.
    public void testApr31() throws Exception {
        int day = 31;
        int month = 4;
        int year = 2006;
        try {
            CompositeDate subject = new CompositeDate(year, month, day);
            fail("Exception not thrown");
        }
        catch (InvalidDateException ex) {
        }
    }
February requires similar tests for the 30th and 31st (not shown here). But February 29 requires two separate test cases: when a year is not evenly divisible by 4 and a century is not evenly divisible by 400.
    public void testFeb29NoLeap() throws Exception {
        int day = 29;
        int month = 2;
        int year = 2003;
        try {
            CompositeDate subject = new CompositeDate(year, month, day);
            fail("Exception not thrown");
        }
        catch (InvalidDateException ex) {
        }
    }
	
    public void testFeb29NoLeap1900() throws Exception {
        int day = 29;
        int month = 2;
        int year = 1900;
        try {
            CompositeDate subject = new CompositeDate(year, month, day);
        fail("Exception not thrown");
        }
        catch (InvalidDateException ex) {
        }
    }
At this point, we have thoroughly tested the constructor for the class under test, CompositeDate. Under most circumstances on many projects, this is good enough. It should be obvious by now, though, that there is considerable code repetition throughout this TestCase. If we're serious about our unit testing and need to keep these tests maintained, we may want to have a second look. We'll start to do something about that by Removing Duplicate Code.
Previous Next