Labs ICT
โญ Pro Login

Assertions in JUnit

Assertions are the heart of JUnit testing. Without them, you are just running code without checking if it does the right thing. JUnit 5 provides a rich set of assertion methods that let you verify everything from simple equality to complex exception handling.

Basic Assertions

Let us start with the assertions you will use most often:


import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;

class AssertionsDemoTest {

    @Test
    void assertEqualsDemo() {
        assertEquals(4, 2 + 2);
        assertEquals("hello", "hello");
        assertEquals(3.14, 3.14, 0.001); // with delta for floating point
    }

    @Test
    void assertNotEqualsDemo() {
        assertNotEquals(5, 2 + 2);
        assertNotEquals("hello", "world");
    }

    @Test
    void assertTrueDemo() {
        assertTrue(5 > 3);
        assertTrue("hello".contains("ell"));
    }

    @Test
    void assertFalseDemo() {
        assertFalse(5 < 3);
        assertFalse("hello".contains("xyz"));
    }

    @Test
    void assertNullDemo() {
        String nothing = null;
        assertNull(nothing);

        String something = "hello";
        assertNotNull(something);
    }
}
    

Custom Failure Messages

All assertions accept an optional message parameter. This is incredibly useful when a test fails because it tells you exactly what went wrong:


@Test
void shouldCalculateTotal() {
    int total = calculateTotal(10, 20);
    assertEquals(35, total,
        "calculateTotal should return sum of inputs");
}
    

When this test fails, you get:


org.opentest4j.AssertionFailedError:
    calculateTotal should return sum of inputs
    expected: <35> but was: <30>
    

Without the message, you would just see "expected 35 but was 30" โ€” helpful, but the message makes it crystal clear what the intention was.

Array Assertions

Comparing arrays requires special handling because assertEquals does not work on arrays directly (it would compare references, not contents):


@Test
    void shouldCompareArrays() {
        int[] expected = {1, 2, 3};
        int[] actual = {1, 2, 3};
        assertArrayEquals(expected, actual);
    }

    @Test
    void shouldCompareStringArrays() {
        String[] expected = {"hello", "world"};
        String[] actual = {"hello", "world"};
        assertArrayEquals(expected, actual);
    }
    

Exception Assertions

Testing exceptions is a common need. Use assertThrows:


@Test
    void shouldThrowOnDivisionByZero() {
        Calculator calc = new Calculator();
        assertThrows(ArithmeticException.class,
            () -> calc.divide(10, 0));
    }

    @Test
    void shouldThrowWithMessage() {
        Calculator calc = new Calculator();
        ArithmeticException exception = assertThrows(
            ArithmeticException.class,
            () -> calc.divide(10, 0)
        );
        assertEquals("Cannot divide by zero", exception.getMessage());
    }
    

Group Assertions

When you need to check multiple conditions, use assertAll:


@Test
    void shouldVerifyUser() {
        User user = new User("John", "john@example.com", 25);

        assertAll("user properties",
            () -> assertEquals("John", user.getName()),
            () -> assertEquals("john@example.com", user.getEmail()),
            () -> assertEquals(25, user.getAge())
        );
    }
    

The advantage of assertAll over multiple assertEquals calls is that all assertions run even if some fail. Without assertAll, the first failure stops execution and you do not see the other failures.

Timeout Assertions

You can assert that a method completes within a time limit:


@Test
    void shouldCompleteQuickly() {
        assertTimeout(Duration.ofSeconds(1), () -> {
            // This should finish within 1 second
            int result = calculateExpensiveOperation();
            assertEquals(42, result);
        });
    }
    

Line-Up: JUnit 4 vs JUnit 5 Assertions


+------------------+------------------------+------------------------+
|     Purpose      |     JUnit 4            |     JUnit 5            |
+------------------+------------------------+------------------------+
| Equal            | assertEquals           | assertEquals           |
| Not Equal        | assertNotEquals        | assertNotEquals        |
| True             | assertTrue             | assertTrue             |
| False            | assertFalse            | assertFalse            |
| Null             | assertNull             | assertNull             |
| Not Null         | assertNotNull          | assertNotNull          |
| Arrays Equal     | assertArrayEquals      | assertArrayEquals      |
| Exception        | @Test(expected=...)    | assertThrows(...)      |
| Timeout          | @Test(timeout=...)     | assertTimeout(...)     |
| Fail             | fail()                 | fail()                 |
+------------------+------------------------+------------------------+
    

The JUnit 5 assertions are more powerful and flexible. The exception testing approach in particular is much better โ€” you can inspect the exception, not just check its type.

๐Ÿงช Quick Quiz

Which of these is NOT a valid JUnit 5 assertion?