Гид по технологиям

JUnit Assertions — обзор методов Assertions в JUnit 5

5 min read Тестирование Обновлено 28 Dec 2025
JUnit Assertions: руководство и cheat‑sheet
JUnit Assertions: руководство и cheat‑sheet

Ноутбук с открытым кодом тестов JUnit на экране

Краткое определение

Assertions — статические методы, которые проверяют условия в модульных тестах. Если утверждение не выполняется, тест считается проваленным.

Основные варианты использования и примеры

assertEquals

Метод assertEquals проверяет, что ожидаемое значение равно фактическому. В JUnit 5 существует множество перегрузок: с сообщением об ошибке, с поставщиком сообщения (Supplier), с дельтой для сравнения чисел с плавающей точкой и т.д.

Пример класса, который мы будем тестировать:

package com.program;

public class AssertionsMethods {
    public static int square(int num) {
        return num * num;
    }
}

JUnit‑тест для метода square (корректированные имена для согласованности):

package com.program;

import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.Test;

class AssertionsMethodsTest {
    @Test
    void testSquare() {
        assertEquals(25, AssertionsMethods.square(5));
        assertEquals(36, AssertionsMethods.square(6), "Значения квадрата не совпали.");
        assertEquals(49, AssertionsMethods.square(7), () -> "Значения квадрата не совпали.");
    }
}

Пояснения:

  • assertEquals(expected, actual) — самая простая форма.
  • assertEquals(expected, actual, message) — выводит message при провале.
  • assertEquals(expected, actual, messageSupplier) — вычисляет message лениво через лямбду.

Важно: для чисел с плавающей точкой используйте версию с дельтой: assertEquals(expectedDouble, actualDouble, delta).

assertNull

assertNull проверяет, что объект равен null. В JUnit 5 три основных перегрузки позволяют указывать сообщение или поставщика сообщения.

Пример:

@Test
public void testStringValue() {
    String stringValue = null;
    assertNull(stringValue);
    assertNull(stringValue, "Значение строки не null");
    assertNull(stringValue, () -> "Значение строки не null");
}

Пояснение: использование поставщика сообщений полезно, когда формирование сообщения дорогостоящие операции — сообщение будет создано только при неудаче.

assertTrue

assertTrue проверяет, что условие истинно. В JUnit 5 есть варианты, принимающие Boolean, BooleanSupplier и варианты с сообщениями.

Пример использования всех вариантов:

@Test
void testEvenNumbers() {
    int num1 = 10;
    int num2 = 16;
    int num3 = 26;
    assertTrue(num1 < num2);
    assertTrue(num3 > num2, "Условие не истинно.");
    assertTrue(num1 < num3, () -> "Условие не истинно.");
    assertTrue(() -> num1 % 2 == 0);
    assertTrue(() -> num2 % 2 == 0, "Значение не является чётным.");
    assertTrue(() -> num3 % 2 == 0, () -> "Значение не является чётным.");
}

Короткие определения:

  • BooleanSupplier — функциональный интерфейс, возвращающий boolean; позволяет писать ленивые лямбды.

assertFalse

assertFalse — противоположность assertTrue. При тех же формах аргументов проверяет, что условие ложно.

Пример:

@Test
void testNotEvenNumbers() {
    int num1 = 11;
    int num2 = 17;
    int num3 = 27;
    assertFalse(num2 < num1);
    assertFalse(num2 > num3, "Условие не ложно.");
    assertFalse(num3 < num1, () -> "Условие не ложно.");
    assertFalse(() -> num1 % 2 == 0);
    assertFalse(() -> num2 % 2 == 0, "Значение является чётным.");
    assertFalse(() -> num3 % 2 == 0, () -> "Значение является чётным.");
}

Когда утверждение может не сработать — распространённые ошибки и контрпримеры

  • Неправильное значение expected/actual: перепутаны аргументы, особенно в старых JUnit‑версиях — результат будет «не совпало», хотя код может быть корректным.
  • Сравнение объектов без equals(): при сравнении объектов assertEquals использует equals(); если equals() не переопределён — сравнение по ссылке даст неожиданный результат.
  • Плавающая точка: сравнение double/float без дельты приведёт к ложным провалам из‑за точности.
  • Ленивые сообщения ошибочно используют выражения с побочными эффектами: лямбда‑поставщик вызывается только при провале, но если код в лямбде зависит от состояния, это может ввести в заблуждение.
  • Тесты с побочными эффектами (изменяют состояние) нарушают изоляцию — утверждение может зависеть от предыдущих тестов.

Пример проблемного сравнения объектов:

class Point { int x, y; }
Point p1 = new Point();
Point p2 = new Point();
// если equals не переопределён, assertEquals(p1, p2) провалится

Альтернативы и комплементарные подходы

  • Интеграционные тесты: проверяют взаимодействие компонентов, полезны если unit‑тест не покрывает интеграционные сценарии.
  • Тестирование контрактов через property‑based тесты (пример: jqwik, QuickTheories) — для генерации случайных входных данных.
  • Мокирование (Mockito, MockK): полезно, когда нужно изолировать зависимость и проверять взаимодействия (verify) вместо значений.
  • Бенчмаркинг/производительность (JMH): если цель — проверить поведение при нагрузке, утверждения JUnit не годятся.

Замечание: unit‑тесты не заменяют код‑ревью и статический анализ — они дополняют качество кода.

Ментальные модели и эвристики при написании утверждений

  • Малые шаги: писать тесты по одной обязанности метода.
  • Arrange‑Act‑Assert: разделяйте подготовку, выполнение и проверку.
  • Явные ожидания: проверяйте именно то, что важно; избегайте «больших» assertions, которые завязывают тест на многие детали реализации.
  • Локализация ошибок: сообщение в assert должно объяснить, почему ожидание важно (не просто “failed”).

Практический cheat‑sheet (быстрые подсказки)

  • assertEquals(expected, actual)
  • assertEquals(expected, actual, delta) — для float/double
  • assertNull(obj)
  • assertNotNull(obj)
  • assertTrue(condition)
  • assertFalse(condition)
  • assertThrows(Exception.class, () -> callThatThrows()) — проверка исключений
  • assertAll(“group”, () -> assertEquals(a,b), () -> assertTrue(c)) — группировка утверждений

Пример assertThrows:

@Test
void testException() {
    assertThrows(IllegalArgumentException.class, () -> {
        Integer.parseInt("not a number");
    });
}

Критерии приёмки (что должен выполнять unit‑тест)

  • Изолированность: тест не зависит от внешнего состояния (файлы, БД, сеть) без явного мокирования.
  • Повторяемость: тест должен давать одинаковый результат при повторных запусках.
  • Скорость: unit‑тесты выполняются быстро.
  • Ясность: сообщение об ошибке помогает найти причину провала.

Ролевые чек‑листы

Разработчик:

  • Пишет тесты для критических ветвей кода.
  • Использует ясные assert‑сообщения.
  • Покрывает граничные случаи.

Тестировщик/QA:

  • Проверяет сценарии отказов и исключения.
  • Прогоняет тесты в CI и фиксит нестабильные тесты.

Технический руководитель:

  • Контролирует покрытие и архитектуру тестов.
  • Проверяет, чтобы тесты не тестировали реализацию, а контракт.

Мини‑методология: как быстро ввести Assertions в проект

  1. Выделите критические модули (парсеры, бизнес‑логику, валидаторы).
  2. Пишите тесты для граничных условий и исключений в первую очередь.
  3. Настройте CI на запуск unit‑тестов при каждом PR.
  4. Рефакторите тесты вместе с кодом, следя за скоростью и стабильностью.

Набор тестовых случаев и проверок (примеры для метода square)

  • Позитивный кейс: square(5) == 25
  • Нулевой кейс: square(0) == 0
  • Отрицательное число: square(-3) == 9
  • Большие числа: проверка переполнения (если требуется)

Критерии приёмки для метода square:

  • Все тесты проходят в локальном окружении и в CI.
  • Тесты покрывают нулевой, положительные и отрицательные значения.

Глоссарий в одну строку

  • Unit‑тест: автоматизированный тест, проверяющий работу одной единицы кода (функции/метода).
  • Assertion: утверждение в тесте, проверяющее условие и сигнализирующее о провале, если условие ложно.
  • Supplier/BooleanSupplier: функциональные интерфейсы Java для ленивых сообщений и булевых выражений.

Лучшие практики и советы по безопасности тестов

  • Не храните чувствительные данные (пароли, токены) в тестах.
  • Избегайте зависимости от внешних сервисов; используйте заглушки/моки.
  • Проверяйте, что тесты не изменяют глобальное состояние между запусками.

Короткое резюме

Assertions — центральный инструмент модульного тестирования в JUnit 5. Правильное использование assertEquals, assertNull, assertTrue, assertFalse и других методов помогает быстро локализовать ошибки и поддерживать качество кода. Используйте ленивые поставщики сообщений для дорогих операций, проверяйте сравнение объектов через equals(), а для чисел с плавающей точкой — применяйте дельту. Внедряйте тесты в CI, следуйте правилам из методологии и используйте роли‑чек‑листы для разной ответственности.

Важно: unit‑тесты — часть общей стратегии контроля качества; дополняйте их интеграционными тестами и проверками на уровне систем.

Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

Похожие материалы

Векторы кибератак: типы, защита и план реагирования
Кибербезопасность

Векторы кибератак: типы, защита и план реагирования

Whiteboard в Microsoft Teams — как пользоваться
Productivity

Whiteboard в Microsoft Teams — как пользоваться

Редактирование фото на iPhone — руководство
Фото

Редактирование фото на iPhone — руководство

Windows 11 без учётной записи Microsoft
Руководство

Windows 11 без учётной записи Microsoft

Как установить 7‑Zip на Linux
Архиваторы

Как установить 7‑Zip на Linux

Мастер‑шаблоны презентаций в Figma
Дизайн

Мастер‑шаблоны презентаций в Figma