Рубрики
Без рубрики

Модульное тестирование System.out.println() с помощью JUnit

Узнайте о подходах к тестированию System.out.println.

Автор оригинала: Jonathan Cook.

1. Обзор

При модульном тестировании мы иногда можем захотеть проверить сообщения, которые мы пишем в стандартный вывод через System.out.println() .

Хотя мы обычно предпочитаем структуру ведения журнала прямому взаимодействию со стандартным выводом, иногда это невозможно.

В этом кратком руководстве мы рассмотрим несколько способов модульного тестирования System.out.println() с помощью JUnit .

2. Простой Метод Печати

На протяжении всего этого урока основное внимание в наших тестах будет уделяться простому методу записи в стандартный поток вывода:

private void print(String output) {
    System.out.println(output);
}

Краткое напоминание о том, что переменная out является общедоступным статическим конечным потоком печати объектом, который представляет стандартный поток вывода , предназначенный для использования в системе.

3. Работа С Ядром Java

Теперь давайте посмотрим, как мы можем написать модульный тест, чтобы проверить содержимое того, что мы отправляем в метод println . Однако, прежде чем мы напишем наш фактический модульный тест, нам нужно будет обеспечить некоторую инициализацию в нашем тесте:

private final PrintStream standardOut = System.out;
private final ByteArrayOutputStream outputStreamCaptor = new ByteArrayOutputStream();

@BeforeEach
public void setUp() {
    System.setOut(new PrintStream(outputStreamCaptor));
}

В методе setUp мы переназначаем стандартный выходной поток на новый PrintStream с помощью ByteArrayOutputStream . Как мы увидим, в этом выходном потоке теперь будут печататься значения:

@Test
void givenSystemOutRedirection_whenInvokePrintln_thenOutputCaptorSuccess() {
    print("Hello Baeldung Readers!!");
        
    Assert.assertEquals("Hello Baeldung Readers!!", outputStreamCaptor.toString()
      .trim());
}

После вызова метода print с выбранным текстом мы можем убедиться, что outputStreamCaptor содержит ожидаемое содержимое. Мы вызываем метод trim , чтобы удалить новую строку, которую System.out.println() добавляет.

Поскольку стандартный выходной поток является общим статическим ресурсом, используемым другими частями системы, мы должны позаботиться о восстановлении его в исходное состояние, когда наш тест завершится:

@AfterEach
public void tearDown() {
    System.setOut(standardOut);
}

Это гарантирует, что мы не получим никаких нежелательных побочных эффектов позже в других тестах.

4. Использование Системных Правил

В этом разделе мы рассмотрим аккуратную внешнюю библиотеку под названием Системные правила , которая предоставляет набор правил JUnit для тестирования кода, использующего System класс .

Давайте начнем с добавления зависимости в наш pom.xml :


    com.github.stefanbirkner
    system-rules
    1.19.0
    test

Теперь мы можем продолжить и написать тест, используя SystemOutRule библиотека предоставляет:

@Rule
public final SystemOutRule systemOutRule = new SystemOutRule().enableLog();

@Test
public void givenSystemOutRule_whenInvokePrintln_thenLogSuccess() {
    print("Hello Baeldung Readers!!");

    Assert.assertEquals("Hello Baeldung Readers!!", systemOutRule.getLog()
      .trim());
}

Довольно круто! Используя правило System Out, мы можем перехватывать записи в System.out . Сначала мы начинаем регистрировать все, что записано в System.out , вызывая метод enable Log в нашем правиле. Затем мы просто вызываем getLog , чтобы получить текст, записанный в System.out , так как мы вызвали EnableLog .

Это правило также включает в себя удобный метод, который возвращает журнал, который всегда имеет разделитель строк как \n

Assert.assertEquals("Hello Baeldung Readers!!\n", systemOutRule.getLogWithNormalizedLineSeparator());

5. Использование системных правил с JUnit 5 и лямбдами

В JUnit 5 модель правил была заменена на расширения . К счастью, библиотека системных правил, представленная в последнем разделе, имеет вариант , подготовленный для работы с JUnit 5.

Системная лямбда доступна в Maven Central . Так что мы можем пойти дальше и добавить его в ваш pom.xml :


    com.github.stefanbirkner
    system-lambda
    1.0.0
    test

Теперь давайте реализуем наш тест с использованием этой версии библиотеки:

@Test
void givenTapSystemOut_whenInvokePrintln_thenOutputIsReturnedSuccessfully() throws Exception {

    String text = tapSystemOut(() -> {
        print("Hello Baeldung Readers!!");
    });

    Assert.assertEquals("Hello Baeldung Readers!!", text.trim());
}

В этой версии мы используем метод tap System Out , который выполняет инструкцию и позволяет нам захватывать содержимое, переданное в System.out .

6. Заключение

В этом уроке мы узнали о нескольких подходах к тестированию System.out.println . В первом подходе мы увидели, как перенаправить туда, где мы пишем стандартный поток вывода, используя ядро Java.

Затем мы увидели, как использовать многообещающую внешнюю библиотеку под названием Системные правила, сначала используя правила стиля JUnit4, а затем работая с лямбдами.

Как всегда, полный исходный код статьи доступен на GitHub .