Professional Documents
Culture Documents
03 Junit4
03 Junit4
21-Apr-12
All the old assertXXX methods are the same Most things are about equally easy
JUnit 4 makes it easier to test that exceptions are thrown when they should be JUnit 4 can still run JUnit 3 tests
JUnit 4 provides protection against infinite loops JUnit 4 has some additional features
JUnit 4 requires Java 5 or newer Dont extend junit.framework.TestCase; just use an ordinary class Import org.junit.* and org.junit.Assert.*
Use a static import for org.junit.Assert.* Static imports replace inheritance from junit.framework.TestCase Instead of a setUp method, put @Before before some method Instead of a tearDown method, put @After before some method Instead of beginning test method names with test, put @Test before each test method
Start by importing the JUnit 4 classes you need import org.junit.*; import static org.junit.Assert.*;
Declare any variables you are going to use frequently, typically including an instance of the class being tested MyProgram program; int [] array; int solution;
If you wish, you can declare one method to be executed just once, when the class is first loaded This is for expensive setup, such as connecting to a database
@BeforeClass public static void setUpClass() throws Exception { // one-time initialization code }
If you wish, you can declare one method to be executed just once, to do cleanup after all the tests have been completed
@AfterClass public static void tearDownClass() throws Exception { // one-time cleanup code }
You can define one or more methods to be executed before each test; typically such methods initialize values, so that each test starts with a fresh set
@Before public void setUp() { program = new MyProgram(); array = new int[] { 1, 2, 3, 4, 5 }; }
You can define one or more methods to be executed after each test; typically such methods release resources, such as files
You can have as many @Before and @After methods as you want
You can inherit @Before and @After methods from a superclass; execution is as follows:
Execute the @Before methods in the superclass Execute the @Before methods in this class Execute a @Test method in this class Execute the @After methods in this class Execute the @After methods in the superclass
A test method is annotated with @Test, takes no parameters, and returns no result All the usual assertXXX methods can be used
You can limit how long a method is allowed to take This is good protection against infinite loops The time limit is specified in milliseconds The test fails if the method takes too long
Some method calls should throw an exception You can specify that a particular exception is expected The test will pass if the expected exception is thrown, and fail otherwise
Parameterized tests
Using @RunWith(value=Parameterized.class) and a @Parameters method, you can run the same tests with multiple datasets @RunWith(value=Parameterized.class) public class FactorialTest { private long expected; private int value;
@Parameters public static Collection data() { return Arrays.asList( new Object[ ][ ] { { 1, 0 }, { 1, 1 }, { 2, 2 }, { 120, 5 } }); } public FactorialTest(long expected, int value) { // constructor this.expected = expected; this.value = value; } @Test public void factorial() { assertEquals(expected, new Calculator().factorial(value)); }
} Source: http://today.java.net/pub/a/today/2006/12/07/junit-reloaded.html
Ignoring a test
@Ignore("I dont want Dave to know this doesnt work") @Test public void add() { assertEquals(4, program.sum(2, 2)); }
Test suites
Other stuff
Failed tests now throw an AssertionError, rather than JUnit 3s AssertionFailedError There is now a version of assertEquals for arrays of objects: assertEquals(Object[] expected, Object[] actual)
JUnit 3 had an assertEquals(p, p) method for each kind of primitive p, but JUnit 4 only has an assertEquals(object, object) and depends on autoboxing
A gotcha
long sum(long x, long y) { return x + y; } @Test public void sum() { assertEquals(4, s.sum(2, 2)); } expected: <4> but was: <4> assertEquals no longer exists for primitives, only for objects Hence, the 4 is autoboxed to an Integer, while sum returns a long The error message means: expected int 4, but got long 4 To make this work, change the 4 to a 4L
gives:
As usual, the easiest way to create a test class is just to let your IDE do it for you Here is the recommended test-driven approach
Create a class containing all the stub methods you initially think you will need Have the IDE create the test class, with all the test methods Repeat:
Write a test Make sure the test fails Write the method being tested Make sure the test now succeeds
Note: When you create the test class, NetBeans in particular puts a lot of garbage lines into each test method; you can just delete these and put in your own code
The End