JUnit тестирование: проверка сообщений в логгере Java
Быстрый ответ
Для осуществления проверки содержимого лога с применением JUnit, следует создать мок-аппендер. Если вы работаете с Log4j2, великолепным решением будет использование функционала TestAppender, предназначенного для перехвата сообщений из лога и усовершенствования ассертов. Ниже представлен пример реализации:
import org.apache.logging.log4j.*;
import org.apache.logging.log4j.core.*;
import org.junit.*;
import static org.junit.Assert.*;
public class LoggerTest {
private final Logger logger = LogManager.getLogger();
private final TestAppender testAppender = new TestAppender();
@Before
public void setUp() {
((LoggerContext) LogManager.getContext(false)).getConfiguration().getRootLogger().addAppender(testAppender);
}
@After
public void tearDown() {
((LoggerContext) LogManager.getContext(false)).getConfiguration().getRootLogger().removeAppender(testAppender);
}
@Test
public void logsExpectedMessage() {
logger.debug("Тестовое сообщение");
assertTrue(testAppender.contains("Тестовое сообщение"));
}
private static class TestAppender extends AbstractAppender {
private final StringBuilder logContent = new StringBuilder();
TestAppender() {
super("TestAppender", null, null);
start();
}
@Override
public void append(LogEvent event) {
logContent.append(event.getMessage().getFormattedMessage());
}
public boolean contains(String message) {
return logContent.toString().contains(message);
}
}
}
Добавьте TestAppender перед началом тестирования и не забудьте его отключить после его завершения. Вы можете проверять записи с использованием assert-методов, таких как assertTrue
, указав соответствующее содержимое лога.
Усовершенствование тестов логирования: основные подходы
Используйте ListAppender для более простого доступа
Если желание создать отдельный класс для Appender отсутствует, в этом случае ListAppender поможет решить вашу проблему, предоставив простой доступ к записям лога для тестовых утверждений.
Применяйте внешние библиотеки
Для работы с различными фреймворками великолепно подойдет LogCaptor и другие аналогичные библиотеки, так как они позволяют сократить объем бойлерплейта и упростить проверку логов.
Процесс перехвата системного вывода
Время от времени вам может возникнуть необходимость перехватить системный вывод, и в этом случае на помощь придет OutputCaptureExtension – расширение JUnit 5, которое особенно актуально для Spring Boot, начиная с версии 2.2 и новее.
Визуализация
Подход к тестированию логирования можно сравнить с наблюдением: ваш код выступает в роли наблюдателя, который отслеживает определенные события.
Логгер: [🔍] <-- Сыщик (Appender)
Тест: [📹] <-- Видеонаблюдение (JUnit Test Explorer)
Когда происходит что-то важное:
Событие в коде: 📌 "Пользователь вошёл"
Ожидаемый лог: **"Пользователь успешно вошёл"**
Производится проверка:
Утверждение успешно: 📹 [📌] == **"Пользователь успешно вошёл"** ✅
Утверждение провалено: 📹 [📌] != **"Ожидаемое сообщение"** ❌
Используйте настраиваемый аппендер или фреймворк для создания моков, чтобы сосредоточиться на главной задаче – перехвате нужных сообщений из лога в ходе тестирования.
Продвинутые техники для опытных тестировщиков
Применение матчеров hamcrest
Не ограничивайтесь просто проверками типа assertTrue
. Более выразительные и удобные утверждения можно получить с использованием матчеров hamcrest и функции assertThat
.
Контроль не только за содержанием, но и уровнем логирования
Контроль уровней логирования является таким же важным элементом, как и проверка сообщений. Убедитесь, что ваш логгер записывает сообщения с правильной степенью важности.
Настройка логгера для изоляции тестов
Чтобы обеспечить корректность проведения тестов, настройте логгер таким образом, чтобы избежать влияния логгеров из рабочей среды, например, используя функцию setUseParentHandlers(false)
для предотвращения нежелательных вмешательств.
Полезные материалы
- How to intercept SLF4J (with logback) logging via a JUnit test? – Stack Overflow — подробное обсуждение на Stack Overflow о процессе проверки логов в JUnit тестах.
- Руководство пользователя JUnit 5 — официальное руководство по созданию утверждений с использованием JUnit 5.
- GitHub – portingle/slf4jtesting: SLF4J Testing library — библиотека для тестирования SLF4J с акцентом на параллелизм и инъекцию зависимостей.
- Официальный сайт фреймворка Mockito — использование Mockito для создания моков логгеров в рамках юнит-тестов.
- System Rules – Набор правил JUnit — набор правил JUnit для тестов, которые взаимодействуют с классами System.*.