EMZETT.
Войти

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