Writing Assertions With JUnit 4

After we have finished this lesson, we

  • Can write assertions with the “standard” JUnit 4 API.
  • Understand why we should not use the “standard” JUnit 4 API.

Writing Assertions With JUnit 4

If we want to write assertions by using the “standard” JUnit 4 API, we must use the org.junit.Assert class. It provides a lot of static methods that we can use for writing assertions.

Before we will take a closer look at these methods, we have to know a few basic rules:

  • If we want to specify a custom error message that is shown when our assertion fails, we have to pass this message (a String object) as the first method parameter of the invoked assertion method.
  • If we want to compare two values (or objects), we have to pass these values (or objects) to the invoked assertion method in this order: the expected value (or object) and the actual value (or object).

Let’s find out what kind of assertions we can write with the Assert class.

Asserting Boolean Values

If we want to verify that a boolean value is true, we have to use the assertTrue() method of the Assert class. In order words, we can use one of these two assertions:

 1import org.junit.Test;
 2
 3import static org.junit.Assert.assertTrue;
 4
 5public class BooleanAssertionTest {
 6
 7    private static final boolean TRUE = true;
 8
 9    @Test
10    public void booleanShouldBeTrue() {
11        assertTrue(TRUE);
12        assertTrue("TRUE should be true but was false", TRUE);
13    }
14}

If we want to verify that a boolean value is false, we have to use the assertFalse() method of the Assert class. In order words, we can use one of these two assertions:

 1import org.junit.Test;
 2
 3import static org.junit.Assert.assertFalse;
 4
 5public class BooleanAssertionTest {
 6
 7    private static final boolean FALSE = false;
 8
 9    @Test
10    public void booleanShouldBeFalse() {
11        assertFalse(FALSE);
12        assertFalse("FALSE should be false but was true", FALSE);
13    }
14}

Asserting That an Object Is Null or Is Not Null

If we want to verify that an object is null, we have to use the assertNull() method of the Assert class. In other words, we can use one of these two assertions:

 1import org.junit.Test;
 2
 3import static org.junit.Assert.assertNull;
 4
 5public class ObjectAssertionTest {
 6
 7    @Test
 8    public void nullShouldBeNull() {
 9        Object actual = null;
10
11        assertNull(actual);
12        assertNull(
13			String.format(
14				"Expected actual to be null but was: %s",
15				actual
16			),
17			actual
18		);
19    }
20}

If we want to verify that an object is not null, we have to use the assertNotNull() method of the Assert class. In other words, we can use one of these two assertions:

 1import org.junit.Test;
 2
 3import static org.junit.Assert.assertNotNull;
 4
 5public class ObjectAssertionTest {
 6
 7    @Test
 8    public void objectShouldNotBeNull() {
 9        Object actual = new Object();
10
11        assertNotNull(actual);
12        assertNotNull("Expected actual to be not null but was null",
13			actual
14		);
15    }
16}

Asserting the Equality of Two Values or Objects

If we want to verify that the expected value (or object) is equal to the actual value (or object), we have to use the assertEquals() method of the Assert class. For example, if we want to compare two Integer objects, we can use one of these two assertions:

 1import org.junit.Test;
 2
 3import static org.junit.Assert.assertEquals;
 4
 5public class ObjectAssertionTest {
 6
 7    @Test
 8    public void twoIntegersShouldBeEqual() {
 9        Integer actual = 9;
10        Integer expected = 9;
11
12        assertEquals(expected, actual);
13        assertEquals(
14				String.format(
15					"Expected actual to be: %d but was: %d",
16					expected,
17					actual
18				),
19                expected,
20                actual
21        );
22    }
23}

If we want to verify that the expected value (or object) is not equal to the actual value (or object), we have to use the assertNotEquals() method of the Assert class. For example, if we want to compare two Integer objects, we can use one of these two assertions:

 1import org.junit.Test;
 2
 3import static org.junit.Assert.assertNotEquals;
 4
 5public class ObjectAssertionTest {
 6
 7    @Test
 8    public void twoIntegersShouldNotBeEqual() {
 9        Integer actual = 9;
10        Integer expected = 4;
11
12        assertNotEquals(expected, actual);
13        assertNotEquals(
14				String.format(
15					"Expected actual to not be: %d but was: %d",
16					expected,
17					actual
18				),
19                expected,
20                actual
21        );
22    }
23}

Asserting Object References

If we want to assert that two objects refer to the same object, we have to use the assertSame() method of the Assert class. In other words, we can use one of these two assertions:

 1import org.junit.Test;
 2
 3import static org.junit.Assert.assertSame;
 4
 5public class ObjectAssertionTest {
 6
 7    @Test
 8    public void shouldPointToSameObject() {
 9        Object actual = new Object();
10        Object expected = actual;
11
12        assertSame(expected, actual);
13        assertSame(
14				"Expected two objects to be the same but they are not",
15                expected,
16                actual
17        );
18    }
19}

If we want to assert that two objects do not refer to the same object, we have to use the assertNotSame() method of the Assert class. In other words, we can use one of these two assertions:

 1import org.junit.Test;
 2
 3import static org.junit.Assert.assertNotSame;
 4
 5public class ObjectAssertionTest {
 6
 7    @Test
 8    public void shouldNotPointToSameObject() {
 9        Object actual = new Object();
10        Object expected = new Object();
11
12        assertNotSame(expected, actual);
13        assertNotSame(
14				"Expected two objects to not be the same but they are",
15                expected,
16                actual
17        );
18    }
19}

Asserting the Equality of Two Arrays

If we want to verify that two arrays are equal, we have to use the assertArrayEquals() method of the Assert class. For example, if we want verify that two int arrays are equal, we can use one of these two assertions:

 1import java.util.Arrays;
 2import org.junit.Test;
 3
 4import static org.junit.Assert.assertArrayEquals;
 5
 6public class ArrayAssertionTest {
 7
 8    @Test
 9    public void twoIntArraysShouldBeEqual() {
10        int[] actual = new int[]{2, 5, 7};
11        int[] expected = new int[]{2, 5, 7};
12
13        assertArrayEquals(expected, actual);
14        assertArrayEquals(
15                String.format(
16				"Expected array: %s to be equal to array: %s but it is not",
17                    Arrays.toString(expected),
18                    Arrays.toString(actual)
19                ),
20                expected,
21                actual
22        );
23    }
24}

We can now write different assertions by using the Junit 4 assertion API. Let’s find out why we should not use it.

Why Should We Not Use the “Standard” JUnit 4 Assertions?

I think that the “standard” JUnit 4 assertions have two problems:

  • We need to pass the actual and expected values as method parameters.
  • We need to pass the method parameters in the wrong order (expected and actual).

I think that one characteristic of a good API is that it protects its users from themselves. In other words, a good API tries to prevent programming errors. Unfortunately, I think that the “standard” JUnit 4 assertion API fails to do it.

Let me explain.

Because the JUnit 4 assertion API takes the required information as method parameters, it is crucial that the method parameters are in a logical order. The problem is that I want to give the method parameters in this order: actual and expected.

I think that the best way to demonstrate the difference is to compare these two sentences:

  1. The value Y is returned when we invoke the method X.
  2. When we invoke the method X, the value Y is returned.

The first sentence describes the assertion API of JUnit 4, and the second sentence describes the assertion API I want to use.

If you agree with me, you have probably noticed that using the “standard” JUnit 4 assertions is quite painful because we have to remember to pass the expected and actual values in illogical order. Sooner or later we forget to do it.

Even though this is not the end of the world, because our tests will fail if our assertions won’t pass, I think that we shouldn’t torment ourselves by using an error prone API that makes our tests hard to write.

If you think that the first sentence is makes more sense than the second one, you should use the “standard” JUnit 4 assertions. However, since I don’t think this way, the other lessons of this course won’t use it.

Let’s move on and summarize what learned from this lesson.

Summary

This lesson has taught us X things:

  • If we want to write assertions by using the “standard” JUnit 4 API, we must use the org.junit.Assert class.
  • We know how we can use the org.junit.Assert class.
  • We should not use the JUnit 4 assertion API because it requires us to pass the actual and expected values in the wrong order.

Get the source code from Github