Unit Testing von System.out.println () mit JUnit

1. Übersicht

Beim Unit-Test möchten wir gelegentlich die Nachrichten testen, die wir über System.out.println () in die Standardausgabe schreiben .

Obwohl wir im Allgemeinen ein Protokollierungsframework der direkten Interaktion mit der Standardausgabe vorziehen, ist dies manchmal nicht möglich.

In diesem kurzen Tutorial sehen wir uns einige Möglichkeiten an, wie wir System.out.println () mit JUnit testen können .

2. Eine einfache Druckmethode

In diesem Tutorial liegt der Schwerpunkt unserer Tests auf einer einfachen Methode, die in den Standardausgabestream schreibt:

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

Eine kurze Erinnerung daran, dass die Variable out ein öffentliches statisches endgültiges PrintStream- Objekt ist, das den Standardausgabestream darstellt, der für die systemweite Verwendung vorgesehen ist.

3. Arbeiten mit Core Java

Nun wollen wir sehen, wie wir einen Komponententest schreiben können, um den Inhalt dessen zu überprüfen, was wir an die println- Methode senden . Bevor wir jedoch unseren eigentlichen Komponententest schreiben, müssen wir in unserem Test einige Initialisierungen vornehmen:

private final PrintStream standardOut = System.out; private final ByteArrayOutputStream outputStreamCaptor = new ByteArrayOutputStream(); @BeforeEach public void setUp() { System.setOut(new PrintStream(outputStreamCaptor)); }

In der setUp- Methode weisen wir den Standardausgabestream einem neuen PrintStream mit einem ByteArrayOutputStream neu zu . Wie wir sehen werden, werden in diesem Ausgabestream die Werte jetzt gedruckt:

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

Nachdem wir das nennen Druckverfahren mit dem gewählten Text, können wir dann sicher , dass der outputStreamCaptor den Inhalt enthält , stellen wir erwartet hatten. Wir rufen die Trimmmethode auf, um die neue Zeile zu entfernen, die System.out.println () hinzufügt.

Da der Standardausgabestream eine gemeinsam genutzte statische Ressource ist, die von anderen Teilen des Systems verwendet wird, sollten wir darauf achten, dass der ursprüngliche Status wiederhergestellt wird, wenn unser Test beendet wird:

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

Dies stellt sicher, dass wir später in anderen Tests keine unerwünschten Nebenwirkungen bekommen.

4. Verwenden von Systemregeln

In diesem Abschnitt werfen wir einen Blick auf eine übersichtliche externe Bibliothek namens System Rules, die eine Reihe von JUnit-Regeln zum Testen von Code enthält, der die System- Klasse verwendet .

Beginnen wir mit dem Hinzufügen der Abhängigkeit zu unserer pom.xml :

 com.github.stefanbirkner system-rules 1.19.0 test 

Jetzt können wir einen Test mit der von der Bibliothek bereitgestellten SystemOutRule schreiben :

@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()); }

Ziemlich cool! Mit der SystemOutRule können wir die Schreibvorgänge in System.out abfangen . Zuerst protokollieren wir alles, was in System.out geschrieben wurde, indem wir die enableLog- Methode für unsere Regel aufrufen . Dann rufen wir einfach getLog auf, um den Text in System.out zu schreiben, da wir enableLog aufgerufen haben .

Diese Regel enthält auch eine praktische Methode, die ein Protokoll zurückgibt, das immer das Zeilentrennzeichen \ n hat

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

5. Verwenden von Systemregeln mit JUnit5 und Lambdas

In JUnit5 wurde das Regelmodell durch Erweiterungen ersetzt. Glücklicherweise enthält die im letzten Abschnitt vorgestellte Systemregelbibliothek eine Variante, die für die Arbeit mit JUnit5 vorbereitet ist.

Das System Lambda ist bei Maven Central erhältlich. Also können wir es unserer pom.xml hinzufügen :

 com.github.stefanbirkner system-lambda 1.0.0 test 

Lassen Sie uns nun unseren Test mit dieser Version der Bibliothek implementieren:

@Test void givenTapSystemOut_whenInvokePrintln_thenOutputIsReturnedSuccessfully() throws Exception { String text = tapSystemOut(() -> { print("Hello Baeldung Readers!!"); }); Assert.assertEquals("Hello Baeldung Readers!!", text.trim()); }

In dieser Version verwenden wir die tapSystemOut- Methode, die die Anweisung ausführt und es uns ermöglicht, den an System.out übergebenen Inhalt zu erfassen .

6. Fazit

In diesem Tutorial haben wir einige Ansätze zum Testen von System.out.println kennengelernt . Im ersten Ansatz haben wir gesehen, wie wir umleiten, wo wir den Standardausgabestream mit Kern-Java schreiben.

Dann haben wir gesehen, wie man eine vielversprechende externe Bibliothek namens System Rules verwendet, indem man zuerst Regeln im JUnit 4-Stil verwendet und später mit Lambdas arbeitet.

Wie immer ist der vollständige Quellcode des Artikels auf GitHub verfügbar.