[JAVA] Testen Sie das Verhalten des Protokollausgabeprotokollierers, wenn Sie eine externe Protokollierungs-API wie SLF4J verwenden

Hintergrund

Ich möchte das Protokoll der Protokollausgabe zum Zeitpunkt des Tests überprüfen, wenn ich eine externe Protokollierungs-API wie SLF4J verwende.

Zweck

Verspotten Sie das Protokoll, damit die Ausgabe des Protokolls durch den Testcode gesteuert werden kann

Für diejenigen, die einen kurzen Blick auf den Code werfen möchten: "[Beispielcode](https://qiita.com/yusha3/items/c9576bbe8b6cc5b27897#%E3%82%B5%E3%83%B3%E3%83%97%E3%83%" Sie finden es im Kapitel "AB% E3% 82% B3% E3% 83% BC% E3% 83% 89)".

Ansatz

Ablauf

  1. Definition von ArgmentCaptor
  2. Definieren Sie den Logger der Zielklasse und fügen Sie den Schein-Appender ein.
  3. Fangen Sie den von der Logger-Mock-Instanz angegebenen Aufruf ab.

1. Definition von ArgmentCaptor

  @Captor
  private ArgumentCaptor<LoggingEvent> captorLoggingEvent;

ArgmentCaptor wird verwendet, wenn Sie überprüfen möchten, ob eine Stubbed-Methode in einer Mockito-Klasse ordnungsgemäß aufgerufen wurde oder ob die entsprechenden Argumente an diese Methode übergeben wurden. Dieses Mal werden wir das Argument von LoggingEvent erfassen, bei dem es sich um die Art der Protokollausgabe handelt.

2. Definieren Sie den Logger der Zielklasse und fügen Sie den Schein-Appender ein.

	  @Mock
	  private Appender mockAppender;

      final Logger logger = (Logger) LoggerFactory.getLogger([Zu testender Klassenname].class);
      logger.addAppender(mockAppender);

Definieren Sie Ihre eigene Logger-Variable, ohne @ Slf4j zu verwenden, und fügen Sie dem Logger einen verspotteten Appender hinzu. Appender ist die Schnittstelle zum Festlegen des Protokollausgabeziels. Appender kann mit der Methode addAppender () auf Logger gesetzt werden. Hier können Sie das Protokollausgabeziel von logger verspotten, indem Sie einen nachgebildeten Appender vorbereiten und addAppender () darauf ausführen.

3. Fangen Sie den von der Logger-Mock-Instanz angegebenen Aufruf ab

     verify(mockAppender).doAppend(captorLoggingEvent.capture());
     assertEquals("INFO", captorLoggingEvent.getValue().getLevel().toString());

doAppend hat ein Ereignisobjekt als Argument. Die Rolle der angehängten Appender-Protokollierung

Mit der obigen Methode kann nur das letzte Protokoll abgefangen werden. Weisen Sie einer Liste zu, um alle Protokolle abzufangen.

//Extrahieren Sie nur Anwendungsprotokolle
      List<LoggingEvent> events = captorLoggingEvent.getAllValues().stream()														 
                                  .collect(Collectors.toList());

Beispielcode

Hauptklasse

package com.zozo.tech.search.personalize.api.logic;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

@Component
@Slf4j
public class Sample {

  public void doLogging() {
    log.info("sample");
    log.info("sample access_log.");
    log.info("sample access_log 2.");
  }
}

Testklasse

package com.zozo.tech.search.personalize.api.logic;

import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.verify;

import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.spi.LoggingEvent;
import ch.qos.logback.core.Appender;
import java.util.List;
import java.util.stream.Collectors;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit.jupiter.SpringExtension;

@ExtendWith(SpringExtension.class)
@SpringBootTest
public class SampleTest {

  @Captor
  private ArgumentCaptor<LoggingEvent> captorLoggingEvent;

  @Mock
  private Appender mockAppender;

  @InjectMocks
  @Autowired
  Sample sample;

  @BeforeEach
  void setUp() {
    MockitoAnnotations.initMocks(this);
  }

  @Test
  void test() throws Exception {
    Logger logger = (Logger) LoggerFactory.getLogger(Sample.class);
    logger.addAppender(mockAppender);

    sample.doLogging();

    verify(mockAppender).doAppend(captorLoggingEvent.capture());
    //Überprüfen Sie, ob das INFO-Level-Protokoll ausgegeben wird
    assertEquals("INFO", captorLoggingEvent.getValue().getLevel().toString());

    //Extrahieren Sie nur Anwendungsprotokolle
    List<LoggingEvent> events = captorLoggingEvent.getAllValues().stream()
        .filter(e -> e.getMessage().contains("access_log"))
        .collect(Collectors.toList());

    assertEquals(2, events.size());
  }
}

Referenzmaterial

Recommended Posts

Testen Sie das Verhalten des Protokollausgabeprotokollierers, wenn Sie eine externe Protokollierungs-API wie SLF4J verwenden
[Java] [Spring] Testen Sie das Verhalten des Loggers
Vorsichtsmaßnahmen bei der Verwendung von querySelector () (z. B. ein Gerät bei der Angabe des Namensattributs)
Wenn das Formular wie "Auswählen von Materialisieren" nicht ordnungsgemäß funktioniert
Überprüfen Sie den Inhalt der Protokollausgabe während des Java-Komponententests (kein Mock verwendet).
Verwenden Sie Webmock mit Rspec
Verwendung der Ketten-API
Zeigen Sie die Wettervorhersage mit OpenWeatherMap an, einer externen API in Ruby
[Rails] Testcode mit Rspec
Testen Sie das Verhalten des Protokollausgabeprotokollierers, wenn Sie eine externe Protokollierungs-API wie SLF4J verwenden
Bild-Upload mit CarrierWave ~ Rspec-Test ~
So fügen Sie eine externe Bibliothek ein
[RSpec] Unit Test (mit gem: factory_bot)
[Für Rails-Anfänger] Zusammenfassung der Verwendung von RSpec (Überblick)
Java Artery - Einfach zu verwendende Unit-Test-Bibliothek
[Docker] Erstellen einer Umgebung für Hugo
So spielen Sie eine MIDI-Datei mit der Java Sound API ab (geben Sie das zu verwendende MIDI-Gerät an)