TGViewer
Java: fill the gaps Java: fill the gaps @java_fillthegaps · 12.3K subscribers
Post #479 11.9K
JUnit: самое важное

Информация ниже не новая, но очень важная. Так что грех не повторить:)

Ниже особенности и фичи JUnit, которые полезно знать большинству разработчиков. Если что-то заинтересовало и непонятно — поможет JUnit 5 User Guide

1️⃣ Жизненный цикл теста

Каждый тест — это метод с аннотацией @Test.

Через аннотацию @DisplayName задаётся симпатичное имя теста в отчёте.

Чтобы выполнить что-то до или после выполнения теста, используются методы с аннотациями:
▫️ @Before, @BeforeAll
▫️ @After, @AfterAll

JUnit создаёт новый экземпляр класса на каждый тестовый метод. Класс ServiceTest с пятью методами @Test во время запуска превратится в 5 экземпляров класса ServiceTest.

Благодаря этому тесты выполняются независимо.

Этим JUnit отличается от TestNG, где создаётся один экземпляр класса на все тестовые методы. Если хочется как в TestNG, добавьте над классом аннотацию @TestInstance(Lifecycle.PER_CLASS)

2️⃣ Проверки

Сердце каждого теста - методы с приставкой assert*:
🔸 assertTrue
🔸 assertEquals
🔸 assertInstanceOf

В самом JUnit мало методов, более удобные ассерты есть в библиотеках Hamсrest и AssertJ. AssertJ, на мой взгляд, более читабельный, но Hamсrest используется чаще.

3️⃣ Группировка тестов

Аннотация @Tag("groupName") объединяет тесты в группы. Работает и для одного теста, и для класса.

Можно указывать тэги в системе сборки и при запуске тестов из IDE.

4️⃣ Отключение тестов

Аннотация @Disabled. Есть продвинутые варианты, можно отключить тесты для
▫️ операционной системы
@DisabledOnOs(WINDOWS)
▫️ версии java
@DisabledOnJre(JAVA_9)
@DisabledForJreRange(min = JAVA_9)
▫️ системных переменных:
@DisabledIfSystemProperty(named = "ci-server", matches = "true")
@DisabledIfEnvironmentVariable(named = "ENV", matches = ".*development.*")

5️⃣ Параметризированные тесты

Помогают запустить один тест с разными аргументами. Выглядит так:

@ParameterizedTest
@ValueSource(ints={100,-14})
public void test(int input) {}

Такой тест запустится дважды - с аргументом 100 и -14.

Вместо готового списка можно брать значения
🔸 из CSV файла @CsvSource
🔸 из метода @MethodSource

6️⃣ Проверка таймаута

▫️ Через ассерт
assertTimeout(ofMinutes(2), ()->{});
▫️ Через аннотацию
@Timeout(value=42,unit=SECONDS)

7️⃣ Полезные библиотеки

▫️ Hamсrest, AssertJ — расширенные библиотеки методов-ассертов
▫️ Mockito для заглушек. Добавляете библиотеку в pom.xml или build.gradle, а в тест - аннотацию @ExtendWith(MockitoExtension.class)
▫️ Testcontainers для запуска внешних компонентов в докере. Добавляем библиотеку, аннотацию @Testcontainers над классом и @Container над компонентом
▫️ Java Faker — генератор данных для тестов

Ещё я когда-то писала 2 хороших поста на тему, чем отличается JUnit 4 от Unit 5. Если вас удивляет, почему там разные аннотации и почему версии не совместимы друг с другом, то почитайте:)
  • 🔥 124
  • 👍 64
  • ❤ 10
  • 👎 1
More from @java_fillthegaps
  1. Apr 30, 2026Get Your Hands Dirty on Clean Architecture: отзыв на книгу Когда я подняла тему чистой арх…
  2. Apr 27, 2026​Clean Architecture: отзыв на книгу Наконец-то дочитала книгу Clean Architecture Роберта М…
  3. Mar 4, 2026Как переиспользовать контекст в интеграционных тестах Сегодня расскажу базовый минимум для…
  4. Mar 4, 2026Post #660
  5. Mar 4, 2026Тестовый контекст поднимается 2 минуты. У нас 4 класса с интеграционными тестами, их конфи…
  6. Feb 25, 2026Чистая архитектура. Главы 3-5 Продолжаем спидран по Clean Architecture Роберта Мартина. ⭐️…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →