javaintermediate

JUnit 5 — Test Patterns and Assertions

Write JUnit 5 tests with assertions, lifecycle hooks, nested tests, parameterized tests, and dynamic tests.

java
import org.junit.jupiter.api.*;
import org.junit.jupiter.params.*;
import org.junit.jupiter.params.provider.*;
import static org.junit.jupiter.api.Assertions.*;
import java.time.Duration;
import java.util.List;
import java.util.stream.Stream;

class CalculatorTest {
    Calculator calc;

    @BeforeEach
    void setup() { calc = new Calculator(); }

    @Test
    @DisplayName("should add two numbers")
    void testAdd() {
        assertEquals(5, calc.add(2, 3));
        assertEquals(0, calc.add(-1, 1));
    }

    @Test
    void testDivideByZero() {
        var ex = assertThrows(ArithmeticException.class,
            () -> calc.divide(10, 0));
        assertTrue(ex.getMessage().contains("zero"));
    }

    @Test
    void testTimeout() {
        assertTimeout(Duration.ofMillis(500), () -> calc.slowOp());
    }

    @Test
    void testMultipleAssertions() {
        assertAll("grouped",
            () -> assertEquals(4, calc.add(2, 2)),
            () -> assertEquals(0, calc.add(1, -1)),
            () -> assertTrue(calc.add(1, 1) > 0)
        );
    }

    // Parameterized tests
    @ParameterizedTest(name = "{0} + {1} = {2}")
    @CsvSource({ "1,2,3", "0,0,0", "-1,1,0", "100,200,300" })
    void testAddParameterized(int a, int b, int expected) {
        assertEquals(expected, calc.add(a, b));
    }

    @ParameterizedTest
    @MethodSource("provideStrings")
    void testIsBlank(String input, boolean expected) {
        assertEquals(expected, input == null || input.isBlank());
    }

    static Stream<Arguments> provideStrings() {
        return Stream.of(
            Arguments.of(null, true),
            Arguments.of("", true),
            Arguments.of("  ", true),
            Arguments.of("hello", false)
        );
    }

    @Nested
    @DisplayName("edge cases")
    class EdgeCases {
        @Test
        void maxValues() {
            assertEquals(Integer.MAX_VALUE, calc.add(Integer.MAX_VALUE, 0));
        }
    }
}

Use Cases

  • Unit testing Java applications with JUnit 5
  • Data-driven testing with parameterized tests
  • Organizing tests with nested test classes

Tags

Related Snippets

Similar patterns you can reuse in the same workflow.