Golang で標準出力をテストする
はじめに
Golang で fmt.Printf などの標準出力結果をテストしたい場合、出力をキャプチャすることでテストが可能になります。
標準出力するプログラム
例として物凄く単純な標準出力するだけの関数を用意します。
func print(str string) { fmt.Printf("%s", str) }
出力のキャプチャ
出力をキャプチャするには出力先を一時的に切替て、出力結果を値として取得することで実現可能です。
fmt.Printf
の出力先である os.Stdout
の型は *os.File
です。
*os.File
で出力を受けて、値を取得するには os.Pipe()
が役に立ちます。
os.Pipe()
は戻り値として writer
と reader
が取得できます。
つまり出力先を os.Stdout
から writer
に切り替えて、 reader
から値を取得することでキャプチャが可能となります。
それではテストコードを見ていきましょう。
テストコード
func TestPrint(t *testing.T) { r, w, err := os.Pipe() if err != nil { t.Fatal(err) } stdout := os.Stdout os.Stdout = w print("hoge") os.Stdout = stdout w.Close() var buf bytes.Buffer io.Copy(&buf, r) if buf.String() != "hoge" { t.Errorf("print() = %s, want hoge", buf.String()) } }
順を追って説明しましょう。
r, w, err := os.Pipe() if err != nil { t.Fatal(err) } stdout := os.Stdout os.Stdout = w
まずテストする関数を呼び出す前に os.Pipe()
で reader
と writer
を生成します。
そして 標準出力の出力先を os.Stdout
から writer
に切り替えます。
print("hoge") os.Stdout = stdout w.Close()
次に関数を実行したら出力先を元の os.Stdout
に戻します。
writer
もクローズします。
var buf bytes.Buffer io.Copy(&buf, r)
最後に reader
から buffer へ値を渡します。
まとめ
Golang で標準出力をテストする場合は os.Pipe()
を駆使して出力先を切り替えて値をキャプチャしましょう。