13.9 テストが書きにくいものをテストする

Goでも他の言語でも、外界とつながるコードのテストはやっかいです。Goに限らず、外部との入出力をメモリへの読み書きに置き換えられればテストはかなり簡単になります。このような、テストが難しいものをテストしやすくするためのTipsがいくつかあります。

13.9.1 シンプルな入出力のテスト

「4.1  柔軟なコードを書くインタフェースの利用法 」で紹介したように、コアとなるロジックはなるべく抽象化された入出力のインタフェース(io.Readerio.Writer)に対して実装するようにしておくと、テストしやすくなります。仮に入出力先がファイルや、外部サーバーとのTCPによるネットワーク通信だけと要件が絞られていたとしても、あえてio.Readerなどに処理をするコードにして、ファイル名で簡単に読み書きできるAPIはプリミティブな実装へのラッパーとして実装するのがおすすめです。

strings.Readerや、bytes.Bufferを使うことで、io.Readerio.Writerを対象としたテストの中では文字列を使って入力値や出力値を書けます1。ファイル、標準入出力はすべてio.Readerio.Writerに対する処理として実装しておくと同じようにテストできます。

// テスト対象
type User struct {
	Name    string
	Address string
}

func DumpUser(u *User) {
	DumpUserTo(os.Stdout, u)
}

func DumpUserTo(w io.Writer, u *User) {
	if u.Address == "" {
		fmt.Fprintf ...