1. 概要

単体テストでは、 System.out.println()を介して標準出力に書き込むメッセージをテストしたい場合があります。

通常、標準出力との直接の対話よりも ロギングフレームワークを優先しますが、これが不可能な場合もあります。

このクイックチュートリアルでは、JUnitを使用してSystem.out.println()を単体テストできるいくつかの方法を見ていきます。

2. 簡単な印刷方法

このチュートリアル全体を通して、テストの焦点は、標準の出力ストリームに書き込む単純なメソッドになります。

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

out変数はpublicstatic final PrintStream オブジェクトであり、システム全体での使用を目的とした標準出力ストリームを表します。

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メソッドで、ByteArrayOutputStreamを使用して標準出力ストリームを新しいPrintStreamに再割り当てします。 これから説明するように、この出力ストリームは、値が出力される場所です。

@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ルールを提供するシステムルールと呼ばれる優れた外部ライブラリを見ていきます。

依存関係pom.xmlに追加することから始めましょう。

<dependency>
    <groupId>com.github.stefanbirkner</groupId>
    <artifactId>system-rules</artifactId>
    <version>1.19.0</version>
    <scope>test</scope>
</dependency>

これで、ライブラリが提供する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());
}

かなりクール! SystemOutRuleを使用して、への書き込みをインターセプトできます System.out。 まず、書き込まれたすべてのログを記録し始めます System.out を呼び出すことによって enableLog 私たちのルールの方法。 次に、 enableLog を呼び出したので、 getLog を呼び出すだけで、System.outに書き込まれるテキストを取得します。

このルールには、常に行区切り文字が \nであるログを返す便利なメソッドも含まれています。

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

5. JUnit5とLambdasでのシステムルールの使用

JUnit5 では、ルールモデルが拡張機能に置き換えられました。 幸い、前のセクションで示したシステムルールライブラリには、JUnit5で動作するように準備されたバリエーションがあります。

System Lambdaは、 MavenCentralから入手できます。 したがって、先に進んでpom.xmlに追加できます。

<dependency>
    <groupId>com.github.stefanbirkner</groupId>
    <artifactId>system-lambda</artifactId>
    <version>1.0.0</version>
    <scope>test</scope>
</dependency>

次に、このバージョンのライブラリを使用してテストを実装しましょう。

@Test
void givenTapSystemOut_whenInvokePrintln_thenOutputIsReturnedSuccessfully() throws Exception {

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

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

このバージョンでは、はtapSystemOutメソッドを使用します。このメソッドは、ステートメントを実行し、System.outに渡されたコンテンツをキャプチャできるようにします。

6. 結論

このチュートリアルでは、System.out.printlnをテストするためのいくつかのアプローチについて学習しました。 最初のアプローチでは、コアJavaを使用して標準出力ストリームを書き込む場所をリダイレクトする方法を確認しました。

次に、最初にJUnit 4スタイルのルールを使用し、次にラムダを使用して、システムルールと呼ばれる有望な外部ライブラリを使用する方法を確認しました。

いつものように、記事の完全なソースコードは、GitHubから入手できます。