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