Annotations
JUnit 4.x uses annotations to mark methods and to configure the test run. The following table gives an overview of the most important available annotations.
Annotation | Description |
---|---|
@Test |
The @Test annotation identifies a method as a test method. |
@Test (expected = Exception.class) | Fails if the method does not throw the named exception. |
@Test(timeout=100) | Fails if the method takes longer than 100 milliseconds. |
@Before public void method() | This method is executed before each test. It is used to prepare the test environment (e.g., read input data, initialize the class). |
@After public void method() | This method is executed after each test. It is used to cleanup the test environment (e.g., delete temporary data, restore defaults). It can also save memory by cleaning up expensive memory structures. |
@BeforeClass public static void method() |
This method is executed once, before the start of all tests. It is used to perform time intensive activities, for example, to connect to a database. Methods marked with this annotation need to be defined as static to
work with JUnit. |
@AfterClass public static void method() |
This method is executed once, after all tests have been finished. It is used to perform clean-up activities, for example, to disconnect from a database. Methods annotated with this annotation need to be defined as static to
work with JUnit. |
@Ignore | Ignores the test method. This is useful when the underlying code has been changed and the test case has not yet been adapted. Or if the execution time of this test is too long to be included. |
Assert Statement
JUnit provides static methods in the Assert
class
to test for certain conditions. These assertion methods typically
start with assert
and
allow you to specify the error message, the expected and the actual result. An assertion method compares
the actual value returned by a test to the expected value, and throws an AssertionException
if
the comparison test fails.
Statement | Description |
---|---|
fail(String) | Let the method fail. Might be used to check that a certain part of the code is not reached or to have a failing test before the test code is implemented. The String parameter is optional. |
assertTrue([message], boolean condition) | Checks that the boolean condition is true. |
assertFalse([message], boolean condition) | Checks that the boolean condition is false. |
assertEquals([String message], expected, actual) | Tests that two values are the same. Note: for arrays the reference is checked not the content of the arrays. |
assertEquals([String message], expected, actual, tolerance) | Test that float or double values match. The tolerance is the number of decimals which must be the same. |
assertNull([message], object) | Checks that the object is null. |
assertNotNull([message], object) | Checks that the object is not null. |
assertSame([String], expected, actual) | Checks that both variables refer to the same object. |
assertNotSame([String], expected, actual) | Checks that both variables refer to different objects. |
Testing exception
@Test
(expected = Exception.class)
annotation is limited as it can only test for one exception. To test exceptions, you can use the following test pattern.
The @Test
(expected = Exception.class)
annotation is limited as it can only test for one exception. To test exceptions, you can use the following test pattern.
try { mustThrowException(); fail(); } catch (Exception e) { // expected // could also check for message of exception, etc. }
Parameterized test
You mark a test class as a parameterized test with the @RunWith(Parameterized.class)
annotation.
Such a test class must contain a static method annotated with @Parameters
that generates
and returns a collection of arrays. Each item in this collection is used as parameter for the test method.
You also need to create a constructor in which you store the values for each test. The number of elements in each array provided by the method annotated with @Parameters
must
correspond to the number of parameters in the constructor of the class. The class is created for each parameter and the test values are passed via the constructor to the class.
The following code shows an example for a parameterized test. It assumes that you test the multiply()
method
of the MyClass
class which was used in an example earlier.
package de.vogella.junit.first; import static org.junit.Assert.assertEquals; import java.util.Arrays; import java.util.Collection; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import org.junit.runners.Parameterized.Parameters; @RunWith(Parameterized.class) public class MyParameterizedClassTest { private int multiplier; public MyParameterizedClassTest(int testParameter) { this.multiplier = testParameter; } // creates the test data @Parameters public static Collection<Object[]> data() { Object[][] data = new Object[][] { { 1 }, { 5 }, { 121 } }; return Arrays.asList(data); } @Test public void testMultiplyException() { MyClass tester = new MyClass(); assertEquals("Result", multiplier * multiplier, tester.multiply(multiplier, multiplier)); } }
Rules
If you run this test class, the test method is executed with each defined parameter. In the above example the test method is executed three times.
@Rule
annotation
you can create objects which can be used and configured in your test methods. This adds more flexibility to your tests. You could, for example, specify which exception message you expect during execution of your test code.
package de.vogella.junit.first; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; public class RuleExceptionTesterExample { @Rule public ExpectedException exception = ExpectedException.none(); @Test public void throwsIllegalArgumentExceptionIfIconIsNull() { exception.expect(IllegalArgumentException.class); exception.expectMessage("Negative value not allowed"); ClassToBeTested t = new ClassToBeTested(); t.methodToBeTest(-1); } }
JUnit already provides several useful implementations of rules. For example, the TemporaryFolder
class
allows to setup files and folders which are automatically removed after a test.
The following code shows an example for the usage of the TemporaryFolder
implementation.
package de.vogella.junit.first; import static org.junit.Assert.assertTrue; import java.io.File; import java.io.IOException; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; public class RuleTester { @Rule public TemporaryFolder folder = new TemporaryFolder(); @Test public void testUsingTempFolder() throws IOException { File createdFolder = folder.newFolder("newfolder"); File createdFile = folder.newFile("myfilefile.txt"); assertTrue(createdFile.exists()); } }
To write your custom rule, you need to implement the TestRule
interface.