4.2.1 Problem
You want to write unit tests with JUnit.
4.2.2 Solution
Create a subclass of junit.framework.TestCase.
Each unit test is represented by a testXXX( )
method within the
TestCase subclass.
4.2.3 Discussion
Example 4-1 shows an extremely simple test case. A
test case is a subclass of
TestCase and contains a collection of unit tests.
Instances of TestCase are sometimes referred to as
test fixtures, although
we prefer to say "test case" since
that matches the class name. Each unit test is a public, no-argument
method beginning with "test". If
you do not follow this naming convention, JUnit will not be able to
locate your test methods automatically. Instead, you would have to
write a suite( ) method and construct instances of
your test case, passing the test method name
to the constructor.
Example 4-1. Simple test case
package com.oreilly.javaxp.common;
import junit.framework.TestCase;
/**
* Sample unit tests for the {@link Person} class.
*/
public class TestPerson extends TestCase {
/**
* This constructor is only required in JUnit 3.7 and earlier.
* @param testMethodName the name of the test method to execute.
*/
public TestPerson(String testMethodName) {
super(testMethodName);
}
/**
* A unit test to verify the name is formatted correctly.
*/
public void testGetFullName( ) {
Person p = new Person("Aidan", "Burke");
assertEquals("Aidan Burke", p.getFullName( ));
}
/**
* A unit test to verify that nulls are handled properly.
*/
public void testNullsInName( ) {
Person p = new Person(null, "Burke");
assertEquals("? Burke", p.getFullName( ));
// this code is only executed if the previous assertEquals passed!
p = new Person("Tanner", null);
assertEquals("Tanner ?", p.getFullName( ));
}
}
In JUnit 3.7 and earlier, the constructor is required and must have
the signature shown in the TestPerson class. JUnit
uses this constructor to create a new instance of the test case as it
runs each of the unit test methods. The name
argument matches the current unit test's method
name, allowing JUnit to use reflection to invoke the corresponding
method. JUnit 3.8 removed the need for this constructor, so we will
not include it in the remaining examples in this chapter.
The "test" methods are the actual
unit tests. You must have at least one unit test in each test case or
JUnit reports an error. Our
TestPerson class has two unit tests, each of which
checks different aspects of the Person
class's getFullName( ) method.
Test methods should follow this signature:
public void test<something>( ) [throws SomeException]
This naming
convention allows JUnit to locate unit tests by reflection. Tests may
throw any subclass of java.lang.Throwable. When
this happens, JUnit catches the exception and reports a test error.
It continues to execute any additional test methods.
Each unit test uses various assertXXX( )
methods to do the actual testing:
assertEquals("Aidan Burke", p.getFullName( ));
This method confirms that its two arguments are equal. If the
arguments are equal, the test passes. Otherwise, a test failure is
reported and the remainder of the current test method is skipped.
JUnit does proceed to execute other test methods, however. In the
case of Object arguments (such as two
Strings), the .equals( ) method
is used for checking equality.
To compile TestPerson, include
junit.jar in your classpath. The next recipe
shows how to run the tests.
4.2.4 See Also
Recipe 4.3 shows how to run your tests. Recipe 4.4 explains the assert( )
methods. Recipe 4.5 describes how fine-grained your
tests should be.