Добавить в корзинуПозвонить
Найти в Дзене
Записки о Java

Unit-тесты в Java

В современной разработке программного обеспечения unit-тестирование — не просто рекомендация, а необходимость. Unit-тесты помогают убедиться, что отдельные части вашего кода работают корректно, упрощают рефакторинг и повышают общую надёжность приложения. В этой статье мы подробно рассмотрим, как писать unit-тесты в Java 11 с использованием популярного фреймворка JUnit 5, а также познакомимся с Mockito для мокирования зависимостей. Unit-тест — это автоматизированный тест, проверяющий корректность работы отдельной «единицы» кода (обычно метода или класса) в изоляции от остальной системы. JUnit — самый популярный фреймворк для unit-тестирования в Java. Версия JUnit 5 (также известная как Jupiter) — это полная переработка по сравнению с JUnit 4 и включает множество современных возможностей. Mockito — библиотека для создания моков (mocks) — объектов, имитирующих поведение реальных зависимостей. Это позволяет тестировать код в изоляции. Для начала добавим зависимости в pom.xml: Допустим, у н
Оглавление
Рисунок: Unit тестирование в Java
Рисунок: Unit тестирование в Java

Введение

В современной разработке программного обеспечения unit-тестирование — не просто рекомендация, а необходимость. Unit-тесты помогают убедиться, что отдельные части вашего кода работают корректно, упрощают рефакторинг и повышают общую надёжность приложения. В этой статье мы подробно рассмотрим, как писать unit-тесты в Java 11 с использованием популярного фреймворка JUnit 5, а также познакомимся с Mockito для мокирования зависимостей.

Что такое Unit-тест?

Unit-тест — это автоматизированный тест, проверяющий корректность работы отдельной «единицы» кода (обычно метода или класса) в изоляции от остальной системы.

Основные характеристики хорошего unit-теста:

  • Быстрый: должен выполняться за миллисекунды.
  • Изолированный: не зависит от других тестов или внешних систем (база данных, сеть и т.д.).
  • Повторяемый: всегда даёт один и тот же результат при одинаковых условиях.
  • Автоматизированный: не требует ручного вмешательства.
  • Читаемый: название и структура теста должны быть понятны без дополнительных пояснений.

Инструменты для Unit-тестирования в Java

JUnit 5

JUnit — самый популярный фреймворк для unit-тестирования в Java. Версия JUnit 5 (также известная как Jupiter) — это полная переработка по сравнению с JUnit 4 и включает множество современных возможностей.

Mockito

Mockito — библиотека для создания моков (mocks) — объектов, имитирующих поведение реальных зависимостей. Это позволяет тестировать код в изоляции.

Другие полезные инструменты

  • AssertJ — библиотека для более выразительных и читаемых утверждений.
  • Hamcrest — альтернативная библиотека для утверждений (менее популярна в новых проектах).
  • Testcontainers — для интеграционных тестов с реальными контейнерами (например, базами данных).

Настройка проекта (Maven)

Для начала добавим зависимости в pom.xml:

Рисунок: настройка зависимостей Maven для работы с Unit тестами
Рисунок: настройка зависимостей Maven для работы с Unit тестами

Простой пример: тестируем калькулятор

Допустим, у нас есть простой класс Calculator:

Рисунок: тестируемый класс калькулятор
Рисунок: тестируемый класс калькулятор
Рисунок: тесты для класса калькулятор, часть 1
Рисунок: тесты для класса калькулятор, часть 1
Рисунок: тесты для класса калькулятор, часть 2
Рисунок: тесты для класса калькулятор, часть 2

Объяснение аннотаций и методов:

  • @Test — помечает метод как тестовый.
  • @DisplayName — задаёт человекочитаемое имя теста (отображается в IDE и отчётах).
  • assertEquals(expected, actual) — проверяет равенство.
  • assertThrows(expectedException, executable) — проверяет, что код выбрасывает указанное исключение.
  • Для double используется третий параметр — delta (допустимая погрешность), так как числа с плавающей точкой не всегда точны.

Тестирование с зависимостями: Mockito

Реальные классы часто зависят от других компонентов: репозиториев, сервисов, внешних API. Чтобы протестировать такой класс в изоляции, мы заменяем зависимости на моки.

Пример: UserService

Рисунок: класс, который будем тестировать UserService
Рисунок: класс, который будем тестировать UserService
Рисунок: Интерфейс UserRepository
Рисунок: Интерфейс UserRepository
Рисунок: класс User
Рисунок: класс User

Тест с Mockito

Рисунок: тестируем с помощью Mockito класс UserService, часть 1
Рисунок: тестируем с помощью Mockito класс UserService, часть 1
Рисунок: тестируем с помощью Mockito класс UserService, часть 2
Рисунок: тестируем с помощью Mockito класс UserService, часть 2

Объяснение Mockito-аннотаций:

  • @Mock — создаёт мок-объект интерфейса или класса.
  • @InjectMocks — создаёт экземпляр тестируемого класса и автоматически внедряет в него моки.
  • @ExtendWith(MockitoExtension.class) — активирует Mockito в JUnit 5.
  • when(...).thenReturn(...) — задаёт поведение мока: при вызове метода возвращается указанное значение.

Лучшие практики написания Unit-тестов

1. Используйте соглашение об именовании

Название теста должно описывать:

  • Что тестируется
  • При каких условиях
  • Какой ожидаемый результат

Примеры:

  • shouldReturnEmptyListWhenNoUsersFound()
  • shouldThrowValidationExceptionWhenEmailIsInvalid()

2. Следуйте структуре AAA (Arrange-Act-Assert)

  • Arrange — подготовка данных и зависимостей.
  • Act — вызов тестируемого метода.
  • Assert — проверка результата.

3. Не тестируйте приватные методы

Тестируйте только публичный API. Если приватный метод критически важен — вынесите его в отдельный класс.

4. Избегайте логики в тестах

Тесты не должны содержать if, for, switch. Это усложняет их понимание и снижает надёжность.

5. Покрывайте граничные случаи

  • Пустые коллекции
  • Null-значения
  • Исключительные ситуации
  • Максимальные/минимальные значения

Проверка покрытия кода

Для оценки качества тестов используйте инструменты покрытия, например JaCoCo.

После запуска mvn test отчёт появится в target/site/jacoco/index.html.

Важно: 100% покрытие — не цель. Цель — уверенность в корректности кода.

Заключение

Примеры, рассмотренные в статье, можно найти по адресу:

https://github.com/ShkrylAndrei/blog_yandex/tree/main/src/main/java/info/shkryl/unitTest

https://github.com/ShkrylAndrei/blog_yandex/tree/main/src/test/java/info/shkryl/unitTest