JUnit 5 и Mockito: написание тестов Java
Коротко: JUnit 5 запускает автоматические тесты для Java, Mockito заменяет зависимости заглушками (mock), чтобы отдельные классы можно было проверять изолированно и быстро.
Подробнее: Модульные тесты автоматически проверяют небольшие единицы (методы/классы). Они рано ловят ошибки, облегчают рефакторинг и документируют желаемое поведение. В Java стандарт — JUnit.
Подробности
Первый тест
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
class DiscountTest {
@Test
void tenPercentOfHundred() {
assertEquals(90.0, Discount.apply(100.0, 10), 0.001);
}
@Test
void negativePercentThrows() {
assertThrows(IllegalArgumentException.class, () -> Discount.apply(100.0, -5));
}
}Запуск: mvn test / ./gradlew test / IDE. Структура: подготовка – действие – проверка (arrange – act – assert). Аннотации: @Test, @BeforeEach, @AfterEach, @BeforeAll, @DisplayName, @Disabled, @Nested, @ParameterizedTest с @ValueSource/@CsvSource. Проверки: assertEquals, assertTrue, assertNull, assertAll, assertThrows.
Mockito: заглушки
Если классу нужна база данных, почта или веб-API, в тесте вы заменяете их:
import static org.mockito.Mockito.*;
@Test
void orderSendsMail() {
MailService mail = mock(MailService.class);
PriceService prices = mock(PriceService.class);
when(prices.price("A1")).thenReturn(20.0);
var service = new OrderService(mail, prices);
service.order("A1", "customer@example.org");
verify(mail).send(eq("customer@example.org"), contains("20"));
verifyNoMoreInteractions(mail);
}when(...).thenReturn, verify(...), ArgumentCaptor, spy, @Mock/@InjectMocks с MockitoExtension. Внедрение зависимостей (передача через конструктор) делает классы тестируемыми.
Хорошие тесты
- Небольшие, быстрые, независимые, повторяемые (F.I.R.S.T.), одно поведение на тест, осмысленные имена.
- Граничные случаи: пусто, null, граничные значения, случаи ошибок.
- Тестируйте поведение, а не реализацию; не мокайте всё (объекты-значения используйте напрямую).
- Внедряйте время/случайность (
Clock). - Пирамида тестов: много модульных, меньше интеграционных, мало сквозных тестов; Testcontainers для тестов с настоящей базой данных.
- Покрытие (JaCoCo) — подсказка, а не цель; мутационное тестирование (PIT).
- TDD: сначала тест (красный), затем код (зелёный), затем наведение порядка.
Практика и экзамен
- CI запускает тесты при каждом push; падающие тесты блокируют слияние.
- Поиск ошибок: тест воспроизводит ошибку до исправления (регрессионный тест).
- Spring Boot:
@SpringBootTest,@WebMvcTest, MockMvc (см. Spring). - Типичные ошибки: тесты зависят друг от друга, настоящий доступ к сети/файлам,
Thread.sleep, нестабильные тесты (время/порядок). - Проект IHK: документируйте концепцию тестов/журнал тестов (тестовые случаи, ожидаемый/фактический результат) прослеживаемо.
- Связанное: pytest (Python), Jest/Vitest (JS), обзор видов тестов.
См. также: Обзор видов тестов, Разработка через тестирование, Maven и Gradle, Jest и Vitest