Writing JUnits
Writing JUnits
Contents
Introduction 2
Annotations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
@Before . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
@Test . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
Test Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
assertNull() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
assertNotNull() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
assertSame() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
assertEquals() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
assertArrayEquals() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
assertTrue() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
assertFalse() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
Most Importantly 10
1
Writing JUnits
Introduction
JUnit is a framework for writing unit tests in Java.
When writing a JUnit, it is necessary to import the desired methods and annotations that will be used
for testing.
The @Before annotation is added to any method that should be run before a test is executed. This is
most often used to initialize instance variables that are used in the tests. A method annotated with the
@Before annotation is run before each individual test method is run.
1 import org . junit . Before ;
2
6 @Before
7 public void setUp () {
8 testStructure = new MyDataStructure () ;
9 }
10
11 }
@Test
The @Test annotation is added to any method that should be run as a unit test. These are the methods
that give feedback by giving information about if and how the test code failed. An important thing
to remember is that there is no predetermined order in which these test methods run. This is because
each of the test methods are meant to be independent of each other. This annotation has two optional
arguments: timeout and expected.
timeout is used to set the maximum running time (in milliseconds) that a test will be allowed to run.
If a test runs longer than this value, it is flagged as failed with a TimeoutException.
expected is used to check for thrown exceptions. If a test expects an exception but one of the desired
type is not thrown or no exception is thrown, it is flagged as failed with an ExpectedException.
1 import org . junit . Before ;
2
Writing JUnits
7 @Before
8 public void setUp () {
9 testStructure = new MyDataStructure () ;
10 }
11
12 @Test
13 public void aNormalTest () {
14 }
15
34 }
Test Methods
assertNull()
The assertNull method checks whether the Object passed as the parameter is null. If the parameter
is null, the test passes; otherwise the test will fail and the line number of the failed assertion will be
provided in the logs.
1 import org . junit . Before ;
2 import org . junit . Test ;
3 import static org . junit . Assert . assertNull ;
4
8 @Before
9 public void setUp () {
10 testStructure = new MyDataStructure () ;
11 }
12
3
Writing JUnits
13 @Test
14 public void te s tFirstItemIsNu l l () {
15 assertNull ( testStructure . getFirst () ) ;
16 }
17
18 }
assertNotNull()
The assertNotNull method checks whether the Object passed as the parameter is not null. If the
parameter is not null, the test passes; otherwise the test will fail and the line number of the failed
assertion will be provided in the logs.
1 import org . junit . Before ;
2 import org . junit . Test ;
3 import static org . junit . Assert . assertNotNull ;
4
8 @Before
9 public void setUp () {
10 testStructure = new MyDataStructure () ;
11 }
12
13 @Test
14 public void te s t Fi rs tIt em Is No t Nu l l () {
15 assertNotNull ( testStructure . getFirst () ) ;
16 }
17
18 }
assertSame()
The assertSame method checks whether the two Objects passed as parameters are the exact same
Object (in other words, using ==). If the parameters are not references to the same object, the test will
fail and the line number of the failed assertion will be provided in the logs.
1 import org . junit . Before ;
2 import org . junit . Test ;
3 import static org . junit . Assert . assertSame ;
4
8 @Before
9 public void setUp () {
10 testStructure = new MyDataStructure () ;
11 }
12
13 @Test
14 public void t e s t As s er t Fi rs t I t e mS a m e () {
15 assertSame ( testStructure . getFirst () , testStructure . getFirst () ) ;
16 }
17
4
Writing JUnits
18 @Test
19 public void t e s t A s s e r t D a t a S t r u c t u r e S a m e () {
20 // Guaranteed to fail
21 assertSame ( new MyDataStructure () , testStructure . getFirst () ) ;
22 }
23
24 }
assertEquals()
The assertEquals method checks whether the two Objects passed as parameters are equal using the
equals method of the first parameter. If the parameters are not equal, the test will fail and the line
number of the failed assertion will be provided in the logs.
1 import org . junit . Before ;
2 import org . junit . Test ;
3 import static org . junit . Assert . assertEquals ;
4
8 @Before
9 public void setUp () {
10 testStructure = new MyDataStructure () ;
11 }
12
13 @Test
14 public void t e s t A s s e r t F i r s t I t e m E q u a l s () {
15 assertEquals ( new MyDataStructure () , testStructure ) ;
16 }
17
18 }
assertArrayEquals()
The assertArrayEquals method checks whether the two arrays passed in are equal in length and that,
for each index i, expected[i].equals(actual[i]). If either of these conditions are not true, the test
will fail and the line number of the failed assertion will be provided in the logs.
1 import org . junit . Before ;
2 import org . junit . Test ;
3 import static org . junit . Assert . assertArray Equals ;
4
8 @Before
9 public void setUp () {
10 testStructure = new MyDataStructure () ;
11 }
12
13 @Test
14 public void te s t As se rtA rr ay Is E mp t y () {
15 assert ArrayE quals ( new Object [0] , testStructure . toArray () ) ;
16 }
5
Writing JUnits
17
18 }
assertTrue()
The assertTrue method checks whether the boolean passed as a parameter is true. If the parameters
is not true, the test will fail and the line number of the failed assertion will be provided in the logs.
1 import org . junit . Before ;
2 import org . junit . Test ;
3 import static org . junit . Assert . assertTrue ;
4
8 @Before
9 public void setUp () {
10 testStructure = new MyDataStructure () ;
11 }
12
13 @Test
14 public void t e s t A s s e r t F i r s t I t e m E x i s t s () {
15 assertTrue ( testStructure . hasFirst () ) ;
16 }
17
18 }
assertFalse()
The assertFalse method checks whether the boolean passed as a parameter is false. If the parameters
is not false, the test will fail and the line number of the failed assertion will be provided in the logs.
1 import org . junit . Before ;
2 import org . junit . Test ;
3 import static org . junit . Assert . assertFalse ;
4
8 @Before
9 public void setUp () {
10 testStructure = new MyDataStructure () ;
11 }
12
13 @Test
14 public void t e s t A s s e r t F i r s t I t e m D o e s N o t E x i s t () {
15 assertFalse ( testStructure . hasFirst () ) ;
16 }
17
18 }
It is more effective to write many, short, specific tests rather than a few, large, general tests. This will
allow mistakes made in the classes that are being tested to be easily spotted.
1 import org . junit . Before ;
2 import org . junit . Test ;
3 import static org . junit . Assert . assertTrue ;
4 import static org . junit . Assert . assertFalse ;
5
9 @Before
10 public void setUp () {
11 testStructure = new MyDataStructure () ;
12 }
13
14 @Test
15 public void doNotDoThis () {
16 testStructure . addFirst (1) ;
17 testStructure . addFirst (2) ;
18 testStructure . addFirst (3) ;
19 testStructure . addFirst (4) ;
20 assertTrue ( testStructure . hasFirst () ) ;
21 assertTrue ( testStructure . hasLast () ) ;
22 testStructure . clear () ;
23 assertFalse ( testStructure . hasFirst () ) ;
24 assertFalse ( testStructure . hasLast () ) ;
25 testStructure . addFirst (1) ;
26 testStructure . addFirst (4) ;
27 testStructure . addFirst (2) ;
28 testStructure . addFirst (3) ;
29 assertTrue ( testStructure . hasFirst () ) ;
30 assertTrue ( testStructure . hasLast () ) ;
31 }
32
33 @Test
34 public void doDoThis () {
35 testStructure . addFirst (1) ;
36 testStructure . addFirst (2) ;
37 testStructure . addFirst (3) ;
38 testStructure . addFirst (4) ;
39 assertTrue ( testStructure . hasFirst () ) ;
40 assertTrue ( testStructure . hasLast () ) ;
41 }
42
43 }
In order to save time and headaches, make the names of the test methods as descriptive as possible. You
may want to prefix the name with something like test so that you can easily jump to that test when
that test fails.
7
Writing JUnits
8 @Before
9 public void setUp () {
10 testStructure = new MyDataStructure () ;
11 }
12
13 @Test
14 public void t e s t H a s F i r s t B y A d d i n g E l e m e n t () {
15 testStructure . addFirst (1) ;
16 assertTrue ( testStructure . hasFirst () ) ;
17 }
18
19 @Test
20 public void t e s t H a s F i r s t B y A d d i n g M a n y E l e m e n t s () {
21 testStructure . addFirst (1) ;
22 testStructure . addFirst (2) ;
23 testStructure . addFirst (3) ;
24 testStructure . addFirst (4) ;
25 assertTrue ( testStructure . hasFirst () ) ;
26 }
27
28 }
In the case of an assertion failure for any of the test methods covered above, you can have a message be
printed that may be helpful to the user. This message should be the first argument of the method.
1 assertEquals ( " Root nodes aren ’t equal " , expectedObject ,
actualObject ) ;
2 assertSame ( " Root nodes aren ’t the same " , expectedObject ,
actualObject ) ;
When writing tests that deal with data structures, be sure to test the contents of the entire data
structures. Sometimes, unwanted changes can occur in parts of the data structures that should have
been left untouched.
1 import org . junit . Before ;
2 import org . junit . Test ;
3 import static org . junit . Assert . assertArray Equals ;
4
8 @Before
9 public void setUp () {
10 testStructure = new MyDataStructure () ;
11 }
12
13 @Test
14 public void t e s t B a c k i n g A r r a y H a s F i r s t B y A d d i n g M a n y E l e m e n t () {
8
Writing JUnits
22 expectedArray [0] = 1;
23 expectedArray [1] = 2;
24 expectedArray [2] = 3;
25
28 }
29
30 }
Make sure that complete branch coverage is met. For each method of the class being tested, determine
which order of method calls or which parameters are needed to be passed for each branch of the method
to have occurred. Once these things are determined, write a single test for each branching situation.
Make them deterministic. Avoid relying on randomly generated values, or if randomly generated values
are required, be sure to use a seed that will allow the same sequence of numbers to be generated for each
run of the tests.
Avoid using static variables. Since the order in which the tests are run is not predetermined (and in fact
the tests may be run in parallel), it is unwise to create assertions based on static variables contained
within the test class.
Limit the use of assertTrue and assertFalse to only testing whether a method or variable is true or
false. In the case of an assertion failure, the error messages generated are not helpful.
Know what methods are already provided to you, and use those methods. For example, all implemen-
tations of the java.util.List interface have a standard definition of equals(). Use this instead of
checking the size and object equality yourself.
Avoid looking at your code or “testing” your tests by running your code. The best unit tests are written
by figuring out the expected results for a given input on paper and then creating assert statements
comparing an expected result to the actual result.
Make sure that all edge cases are covered. Try running methods in an uncommon or strange order and
seeing if anything breaks.
9
Writing JUnits
Most Importantly
10