SuperAPI AI Directory

junit

Testing & quality

View repository

Updated 10-15 21:49

About this skill

JUnit 5

JUnit is the programmer-friendly testing framework for Java and the JVM. JUnit 5 is the current major version, composed of the JUnit Platform, JUnit Jupiter, and JUnit Vintage.

When to Use

  • Java & JVM Ecosystem Testing: The gold standard testing framework (JUnit 5 / Jupiter) for Java, Kotlin, and Spring Boot applications.
  • Parameterized & Dynamic Testing: Executing tests across CSV sources, method sources, and enum arguments.
  • Lifecycle Extensions: Customizing test execution with JUnit 5 Extension model (@ExtendWith).
  • Spring Boot Integration Testing: Pairing with @SpringBootTest and MockMvc to test enterprise web applications.

Quick Start

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

class CalculatorTest {
@Test
void addition() {
    assertEquals(2, 1 + 1, "Optional failure message");
}

}


## Core Concepts

### JUnit 5 Architecture (Platform + Jupiter + Vintage)

JUnit 5 separates the test execution engine from the developer API:

```text
[ JUnit Platform (Launcher, IDE & Maven/Gradle Execution) ]
        ├── [ JUnit Jupiter (Modern API, Annotations, Extensions) ]
        └── [ JUnit Vintage (Backward compatibility with JUnit 3/4) ]

Parameterized Tests (@ParameterizedTest)

Executes a test method repeatedly with differing input sets:

import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
import static org.junit.jupiter.api.Assertions.*;

class StringUtilityTest {
    @ParameterizedTest(name = "reverse({0}) should be {1}")
    @CsvSource({
        "radar, radar",
        "hello, olleh",
        "'', ''"
    })
    void testReversal(String input, String expected) {
        assertEquals(expected, StringUtility.reverse(input));
    }
}

Lifecycle Callbacks & Nested Test Contexts

Organizes tests hierarchically with @Nested and handles setup/teardown cleanly:

import org.junit.jupiter.api.*;

class OrderServiceTest {
    @BeforeEach
    void setUp() { /* Common setup */ }

    @Nested
    @DisplayName("When order has no discount")
    class NoDiscount {
        @Test
        void calculatesFullPrice() { /* ... */ }
    }
}

Common Patterns

Parameterized Tests with CSV or Method Source

Problem: Writing multiple @Test methods for different inputs leads to verbose and brittle test classes.

Solution: Use @ParameterizedTest with @CsvSource:

import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
import static org.junit.jupiter.api.Assertions.assertEquals;

class MathUtilsTest {
    @ParameterizedTest(name = "{0} + {1} should equal {2}")
    @CsvSource({
        "1, 2, 3",
        "10, 20, 30",
        "-5, 5, 0"
    })
    void testAddition(int a, int b, int expected) {
        assertEquals(expected, MathUtils.add(a, b));
    }
}

Best Practices

Do:

  • Standardize on JUnit Jupiter (JUnit 5): Remove the legacy junit-vintage-engine dependency from modern projects.
  • Use AssertJ for Fluent Assertions: Pair JUnit with assertThat(result).isNotNull().hasSize(3) for clear assertion failures.
  • Leverage @TempDir for File Tests: Inject temporary directories automatically cleaned up after test completion.
  • Use Display Names: Provide descriptive @DisplayName("Should reject expired payment tokens") annotations.

Don't:

  • Import JUnit 4 annotations: Avoid importing org.junit.Test; always use org.junit.jupiter.api.Test.
  • Make test classes or methods public in JUnit 5: Jupiter classes and methods can and should be package-private.
  • Ignore test execution order: Tests should be completely independent; avoid relying on execution sequences.

Troubleshooting

Error Cause Solution
No tests found matching selector Missing JUnit 5 Jupiter engine dependency in pom.xml / build.gradle. Add org.junit.jupiter:junit-jupiter-engine and enable useJUnitPlatform() in Gradle.
org.opentest4j.AssertionFailedError Expected value does not match actual output. Inspect assertion message: parameter ordering is assertEquals(expected, actual).
IllegalStateException: Failed to load ApplicationContext Spring Boot configuration error during test setup. Check @ContextConfiguration or mock missing beans using @MockBean.

References