Skip to main content
Advertisement

16.2 Writing Unit Tests (JUnit5 + AssertJ)

1. JUnit5 Key Annotations

@DisplayName("UserService Unit Tests")
class UserServiceTest {

@Test
@DisplayName("Registering a duplicate email throws an exception.")
void duplicate_email_throws_exception() {
// Given
UserService userService = new UserService(new FakeUserRepository());

// When / Then
assertThatThrownBy(() -> userService.register("duplicate@test.com", "password"))
.isInstanceOf(DuplicateEmailException.class)
.hasMessageContaining("Email already in use");
}

@ParameterizedTest
@ValueSource(strings = {"invalid", "no-at-sign", ""})
@DisplayName("Invalid email formats throw an exception.")
void invalid_email_format_throws(String invalidEmail) {
assertThatThrownBy(() -> new Email(invalidEmail))
.isInstanceOf(IllegalArgumentException.class);
}

@Nested
@DisplayName("Point deduction tests")
class PointDeductTest {
@Test @DisplayName("Deduction succeeds when points are sufficient.") void sufficient_points() { ... }
@Test @DisplayName("Deduction fails when points are insufficient.") void insufficient_points() { ... }
}
}

2. AssertJ for Readable Assertions

AssertJ provides far more expressive and readable assertions than JUnit5's built-in Assertions.

assertThat(result).isEqualTo(expected);
assertThat(list).hasSize(3).contains("A", "B");
assertThat(user.getName()).isNotNull().startsWith("John");
assertThat(price).isGreaterThan(0).isLessThanOrEqualTo(100_000);

// Exception assertions
assertThatThrownBy(() -> service.dangerousMethod())
.isInstanceOf(CustomException.class)
.hasMessage("Error message");

// Optional assertions
assertThat(optUser).isPresent().hasValueSatisfying(u ->
assertThat(u.getEmail()).isEqualTo("user@example.com")
);
Advertisement