JUnit is a unit testing framework for Java. It allows developers to unit test code elegantly. The latest version of JUnit 4 (Version 4.11) can be downloaded from the following link:
Inheritance in Java is not a smart thing to implement. You cannot extend more than one class.
Previous versions of JUnit had the following drawbacks:
Test classes had to extend the
TestCase
classWe used public methods for setup and teardown; signatures and names were hardcoded
Every test method had to start with a name such as
test<Name>
JUnit 4 is annotation based. Any public method, to act as a setup or teardown, just needs to annotate with @Before
or @After
. Any method, to act as a test method, just needs to annotate the method with @Test
. It provides two more annotations—@BeforeClass
and @AfterClass
. Moreover, there is no need to extend from TestCase
; any POJO class can be a test case.
Open an Eclipse project, add the JUnit 4.0 JAR files to the project classpath, and create a simple class named JUnit4Test.java
.
Add a public void method and annotate it with the @Test
annotation (import org.junit.Test;
):
@Test public void myFirstTest() { System.out.println("Executing myFirstTest"); }
Run the test from Run | Run As | JUnit Test or press Alt + Shift + X and then press T.
It will execute the method and print Executing myFirstTest.
Now add two static public void methods and annotate one with @AfterClass
and the other with @BeforeClass
. Add a default constructor and put the sysout
comment. Now run the test again. It will first execute the static method with the @BeforeClass
annotation and then the constructor, then the test, and finally the @AfterClass
method.
Add two more public methods. Annotate one with @Before
and another with @After
. Now run the test—it will execute @Before
before every test and @After
after every test.
The following is the output from the console:
@BeforeClass is invoked once Constructor is invoked @Before is executed... Executing myFirstTest [test first may get executed after test second] @After is executed... Constructor is invoked @Before is executed... Executing mySecondTest[test second may get executed before test first] @After is executed... @AfterClass is invoked once
@Before
and @After
are used to set up data for testing and cleaning up, such as acquiring a database connection in the @Before
method and closing the connection in the @After
method.
The @Test
annotation takes an argument expected=<<Exception class name>>.class
.
To test a negative test condition, exception handling in the unit test is very important. For example, if an API needs three not-null objects and the caller passes a null argument, the API should throw an exception complaining that the caller is violating the contract. This condition can be easily tested using the JUnit 4 expected
feature. If the API doesn't throw an exception, the test will fail:
@Test(expected= IllegalArgumentException.class) public void exception() { throw new IllegalArgumentException(); }
To run the test suite or multiple test cases, JUnit 4 provides Suite.class
. @Suite.SuiteClasses
takes comma-separated test classes as follows:
import org.junit.runner.RunWith; import org.junit.runners.Suite; @RunWith(Suite.class) @Suite.SuiteClasses({JUnit4Test.class, My2ndTest.class}) public class JunitSuit { }
JUnit provides the Assert
class with many static methods to compare expected and orginal values. Suppose there is a class called Calculator that takes two int
parameters, adds the values, and returns the result. If you want to test this, you can pass value 1
and 2
to the add()
method and expect that 3
will be returned:
@Test public void assertMe() throws Exception { int expected = 1+2; assertEquals(expected, new Calculator().add(1, 2)); }
If the logic in the Calculator class is wrong, the test will fail. In the following code snippet, the Calculator class does not add two arguments, but returns only parameter a. This is wrong; it should add the argument a and b and then return the result:
class Calculator { public int add(int a, int b) { return a; } }
The unit test will complain and ask you to fix this; the preceding JUnit test will fail as the test expects that the add()
method will return 3
, but, in reality, it returns 1
.