2023.08.09  

【Go】テストコードで標準出力(ログ)の内容を判定する方法

Go    

Go言語のテストでlogの内容に想定した文字列が含まれるかどうかチェックする方法のメモ書きです。
下記サイトを参考にさせて頂きましたが、自分のテストしたい関数だと上手くいかなかったので、少しだけ改修しています。
https://zenn.dev/glassonion1/articles/8ac939208bd455

テストする関数

今回テストする関数の内容。

// テスト対象の関数
func Print (moji1 string, moji2 string) error {
    fmt.Print(moji1)
    fmt.Print(moji2)
        return nil
}

テストコードで使用する標準出力を取得する関数

テスト対象の関数を実行し、出力された標準出力の内容を出力する処理を書いています。
テスト対象の関数を実行するの部分の関数を任意の関数に書き換えることで、他のテストにも応用できます。
testExec関数の引数で、テスト対象関数の引数を取得します。

func testExec(t *testing.T, u moji1 string, moji2 string) string {
    t.Helper()

    // 既存のStdoutを退避する
    orgStdout := os.Stdout
    defer func() {
        // 出力先を元に戻す
        os.Stdout = orgStdout
    }()
    // パイプの作成(r: Reader, w: Writer)
    r, w, _ := os.Pipe()
    // Stdoutの出力先をパイプのwriterに変更する
    os.Stdout = w

    // テスト対象の関数を実行する
    if err := Print(moji1, moji1); err != nil {
        t.Fatalf("想定外のエラー: %v", err)
    }

    // Writerをクローズする
    // Writerオブジェクトはクローズするまで処理をブロックするので注意
    w.Close()
    // Bufferに書き込こまれた内容を読み出す
    var buf bytes.Buffer
    if _, err := buf.ReadFrom(r); err != nil {
        t.Fatalf("failed to read buf: %v", err)
    }
    // 文字列を取得する
    return strings.TrimRight(buf.String(), "\n")
}

テストの実装

上記で作成したtestExec関数をテストコード上で呼び出します。
testExec関数の実行結果に標準出力の内容が格納されています。

// テスト関数
func TestPrint(t *testing.T) {
    // テスト対象の関数が出力した文字列を取得する
        moji1 := "hoge"
        moji2 := "fuga"

    result := testExec(t, moji1, moji2)

    // 期待されたログが出力されていることを確認
    if !strings.Contains(result, "hoge") {
        t.Errorf("期待される文字列が出力されませんでした")
    }

    // 期待されたログが出力されていることを確認
    if !strings.Contains(result, "fuga") {
        t.Errorf("期待される文字列が出力されませんでした")
    }
}
コメント
現在コメントはありません。
コメントする
コメント入力

名前 (※ 必須)

メールアドレス (※ 必須 画面には表示されません)

送信