6
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Go言語で標準入出力をスタブする方法

Posted at

#Pipeを駆使してスタブする

結論をここに載せておきます。
https://play.golang.org/p/JtIHncxhGw

##こんな感じの関数をテストしたい!って時です。
https://golang.org/pkg/bufio/#example_Scanner_lines

lines.go
//標準入力を行番号付きで標準出力に出力する。refer to https://golang.org/pkg/bufio/#example_Scanner_lines
func hoge() {
	i := 0
	scanner := bufio.NewScanner(os.Stdin)
	for scanner.Scan() {
		i++
		fmt.Println(i, scanner.Text()) // Println will add back the final '\n'
	}
	if err := scanner.Err(); err != nil {
		fmt.Fprintln(os.Stderr, "reading standard input:", err)
	}
}

##こんな感じで書きます。
入力、出力、エラー出力をそれぞれパイプで乗っ取って、対象を実行した後、元に戻して終了。

lines_test.go
func TestHoge() {
	strout, _ := StubIO("私が標準入力だ\nガハハ", func() {
		hoge()
	})
	fmt.Println("キャプチャした標準出力")
	fmt.Println(strout)
}

// StubIO stubs Stdin Stdout Stderr in 'fn'.return Stdout and Stderr
func StubIO(inbuf string, fn func()) (string, string) {
	inr, inw, _ := os.Pipe()
	outr, outw, _ := os.Pipe()
	errr, errw, _ := os.Pipe()
	orgStdin := os.Stdin
	orgStdout := os.Stdout
	orgStderr := os.Stderr
	inw.Write([]byte(inbuf))
	inw.Close()
	os.Stdin = inr
	os.Stdout = outw
	os.Stderr = errw
	fn()
	os.Stdin = orgStdin
	os.Stdout = orgStdout
	os.Stderr = orgStderr
	outw.Close()
	outbuf, _ := ioutil.ReadAll(outr)
	errw.Close()
	errbuf, _ := ioutil.ReadAll(errr)

	return string(outbuf), string(errbuf)

}

##コピペする前に
既にライブラリ化しましたので、ご自由に使ってください。

"github.com/nak1114/goutil/assert"

import(
    "github.com/nak1114/goutil/assert"
)

func TestHoge() {
	strout, _ := assert.StubIO("私が標準入力だ\nガハハ", func() {
		hoge()
	})
	fmt.Println("キャプチャした標準出力")
	fmt.Println(strout)
}

#Go言語はテスト関連が弱いですね。

自前主義ではないのだけど、Rubyで言うところのWebmockやFakeFSやTimeCopも見当たらないし、その他のスタブもあまり見かけませんね。

Webmock -> Mockサーバ立てろ
FakeFS -> 仮想環境でテストしろ

までは解るのですが、TimeCopはどうしろと。dockerの時間機能をゴニョゴニョするくらいしか思いつかないです。

とりあえず、私が必要と感じたものは逐次"github.com/nak1114/goutil"に追加していこうかなと思っています。

##テストフレームワークは結構好き
テスト対象と同じDirにテストを置いておくのは、行き来がしやすくて便利だと思いました。

##誰かアサーション作って!
テストレポートがいい加減になるからアサーションは提供しないよってのは、作りたくないだけですよね。これも自前で比較関数作るのダルいんだけど、私のググり力が足りないので既存のが見つからないんだよなぁ。Gospelも覗いてみたけどちょっと違う。

6
4
6

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?