Java

Chapter 147: Testing with JUnit in Java — JUnit 5, Lifecycle, Assertions, and Test Slices

Write tests with JUnit 5: @Test, lifecycle annotations, assertions and parameterized tests, nested tests, extensions, and Spring Boot test slices like @WebMvcTest and @DataJpaTest at a glance.

Author: Sushil Kumar

Java JUnit 5 tutorialJava Spring Boot testJava parameterized tests JUnitJava WebMvcTest DataJpaTestJava unit testing best practices

Chapter 147: Testing with JUnit in Java

JUnit 5 (Jupiter) is the default test engine for modern Java and Spring Boot: @Test methods, rich assertions via org.junit.jupiter.api.Assertions, lifecycle hooks, and extensions for Spring, Testcontainers, and more.

Tests are executable specsfast feedback beats manual click retesting.


1. Topic title

JUnit: automate checks; keep tests deterministic, fast, and independent


2. What it means

@BeforeEach / @AfterEach prepare fresh state per testavoid order dependence.

@ParameterizedTest feeds many inputs through @CsvSource or @MethodSource.

Spring @SpringBootTest loads full contextheavy; slices (@WebMvcTest, @DataJpaTest) narrow scope.


3. Why it is used

Regression safety net when refactoring controllers or queries.

Documentation that runsfailing tests prove drift.


4. Mental sketch

Manual QA is tasting every dish before service. JUnit is recipe cards with checkboxeskitchen runs them every commit.


5. Java code example

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
 
import org.junit.jupiter.api.Test;
 
class CalculatorTest {
    @Test
    void adds() {
        assertEquals(3, 1 + 2);
    }
 
    @Test
    void rejectsBadInput() {
        assertThrows(IllegalArgumentException.class, () -> {
            if (true) {
                throw new IllegalArgumentException("demo");
            }
        });
    }
}

assertThrows captures expected failure typesbetter than try/catch in each test.


6. Explanation of code

@DisplayName improves report readability in IDE and CI HTML.


7. Common mistakes

Flaky timing tests—avoid Thread.sleep for synchronization; use Awaitility or proper latches.

Shared mutable statics between testsorder-dependent failures.


8. Best practices

AAA pattern—Arrange, Act, Assertblank lines help readers.

One logical assertion cluster per test namesplit when name needs “and”.


9. Small practice task

Add @ParameterizedTest + @CsvSource for several input/output pairs on a pure function you own.


Beginner tip

If CI fails only on Linux, suspect line endings, locale, or filesystem case sensitivitytests should pin locale when parsing dates.