Gymterview
junior

Что такое AssertJ и чем он лучше стандартных assertions?

AssertJ — библиотека fluent assertions для Java, предоставляющая читаемый и удобный API для написания проверок. Spring Boot включает AssertJ в стартер spring-boot-starter-test по умолчанию.

Преимущества

  • Fluent API — цепочки вызовов читаются как естественный язык
  • IDE-автодополнение — методы подсказываются в зависимости от типа объекта
  • Информативные сообщения об ошибках — при провале теста сразу видно, что пошло не так

Сравнение с JUnit assertions

Пример
// JUnit 5
assertEquals("Иван", user.getName());
assertTrue(list.contains("элемент"));
assertNotNull(user.getEmail());

// AssertJ — читается естественнее
assertThat(user.getName()).isEqualTo("Иван");
assertThat(list).contains("элемент");
assertThat(user.getEmail()).isNotNull();

Работа со строками

Пример
assertThat("Привет, мир!")
    .startsWith("Привет")
    .endsWith("мир!")
    .contains("вет, м")
    .hasSize(13)
    .doesNotContain("ошибка");

Работа с коллекциями

Пример
List<User> users = userService.findAll();

assertThat(users)
    .hasSize(3)
    .isNotEmpty()
    .extracting(User::getName)
    .containsExactly("Иван", "Мария", "Пётр")
    .doesNotContain("Неизвестный");

assertThat(users)
    .filteredOn(user -> user.getAge() > 25)
    .hasSize(2)
    .extracting(User::getName, User::getEmail)
    .containsExactly(
        tuple("Иван", "ivan@example.com"),
        tuple("Пётр", "petr@example.com")
    );

Работа с исключениями

Пример
assertThatThrownBy(() -> userService.findById(999L))
    .isInstanceOf(UserNotFoundException.class)
    .hasMessageContaining("999")
    .hasNoCause();

assertThatCode(() -> userService.findById(1L))
    .doesNotThrowAnyException();

Работа с Optional

Пример
assertThat(userRepository.findByEmail("ivan@example.com"))
    .isPresent()
    .hasValueSatisfying(user -> {
        assertThat(user.getName()).isEqualTo("Иван");
        assertThat(user.getAge()).isGreaterThan(18);
    });

Soft assertions (аналог assertAll в JUnit 5)

Пример
@Test
void shouldValidateUser() {
    User user = userService.findById(1L);

    SoftAssertions.assertSoftly(softly -> {
        softly.assertThat(user.getName()).isEqualTo("Иван");
        softly.assertThat(user.getEmail()).contains("@");
        softly.assertThat(user.getAge()).isGreaterThan(0);
        softly.assertThat(user.getRoles()).isNotEmpty();
    });
    // Все ошибки будут собраны и показаны разом
}

На собеседовании: достаточно показать знание fluent API и пары фич: extracting для коллекций, assertThatThrownBy для исключений. Частая ошибка — путать порядок аргументов в JUnit (assertEquals(expected, actual)) и в AssertJ (assertThat(actual).isEqualTo(expected)).