Unit testing with JUnit 5
JUnit 5 (JUnit Jupiter) is the standard testing framework.
- Mark tests with
@Testand name them by behaviour:appliesFestiveDiscount(). - Follow Arrange, Act, Assert: set up, call the code, check the result.
- Assert with
assertEquals,assertTrueandassertThrows, or AssertJ's readableassertThat(x).isEqualTo(y). @BeforeEachruns before every test; tests must not depend on each other.@ParameterizedTestruns one test with many inputs.@DisplayNameand@Nestedmake reports easier to read.
Good unit tests are fast (milliseconds), isolated (no database or network) and deterministic (same result every run). Run them with ./mvnw test, and in CI on every push.
Example
class PricingTest {
private Pricing pricing;
@BeforeEach
void setUp() {
pricing = new Pricing(new BigDecimal("0.18")); // arrange
}
@Test
void addsGstToThePrice() {
BigDecimal total = pricing.withGst(new BigDecimal("1000")); // act
assertEquals(new BigDecimal("1180.00"), total); // assert
}
@Test
void rejectsNegativePrices() {
var ex = assertThrows(IllegalArgumentException.class,
() -> pricing.withGst(new BigDecimal("-1")));
assertTrue(ex.getMessage().contains("negative"));
}
@ParameterizedTest
@CsvSource({"STUDENT, 500.00", "FESTIVE, 800.00", "NONE, 1000.00"})
void appliesDiscounts(Discount discount, String expected) {
assertEquals(new BigDecimal(expected), pricing.discounted(new BigDecimal("1000"), discount));
}
}Common mistake
Tests that depend on each other's order or on shared static state. Each test must set up what it needs and pass on its own.
Under the hood
Test behaviour through public methods rather than private details, so refactoring doesn't break tests. Aim for meaningful coverage of business rules and edge cases (nulls, empty lists, boundaries) rather than a coverage percentage. Inject a Clock instead of calling now() so time-based rules are testable. JUnit 6 (2025) continues the same Jupiter API with Java 17 as its minimum.
Check yourself
Which JUnit 5 annotation runs before each test?
How this connects
Know these first
Where this leads
Part of Job-ready backend developer.
Was this lesson helpful?
Finished reading? Mark it complete to track your progress.