Goでテストを書きたいときにjsonや大きめの構造体で返ってくる戻り値をテストしたいニーズがありますよね。
そのようなニーズに対して、golang.tokyo#17にて発表されたTips for develoepr-friendly testingのスライドでご紹介いただいた、google/go-cmpを実際に使ってとても便利だったので、ここに使い方を残しておきます。
google/go-cmp
google/go-cmpはGoogle非公式の値比較のライブラリです。
This package is intended to be a more powerful and safer alternative to reflect.DeepEqual for comparing whether two values are semantically equal.
使い方
インストール
go get -u github.com/google/go-cmp/cmp
depなどをお使いの方は別途それぞれの方法で。
Diff
使い方の参考としては、https://godoc.org/github.com/google/go-cmp/cmp#example-Diff--Testing に記載のあるexampleコードがベースです。
例えば、下記のようなメソッドがあった場合を仮定します。
type Hoge struct {
Moji string
AnotherStruct Huga
Num int
Flag bool
}
type Huga struct {
Moji string
}
// Hogeを返す
func FuncHoge() Hoge {
h := Hoge{
Moji: "hogehoge",
AnotherStruct: Huga{
Moji: "hugahuga",
},
Num: 1,
Flag: false,
}
return h
}
上記のメソッドを返り値をチェックする場合は次のように使用します。
func TestFuncHoge(t *testing.T) {
expected := Hoge{
Moji: "hogehoge",
AnotherStruct: Huga{
Moji: "hugahuga",
},
Num: 1,
Flag: false,
}
res := FuncHoge()
if diff := cmp.Diff(res, expected); diff != "" {
t.Errorf("Hogefunc differs: (-got +want)\n%s", diff)
}
}
テストコード内の、cmp.Diff()
がgoogle/go-cmp
が提供している機能です。
func Diff(x, y interface{}, opts ...Option) string
戻り値がstring型で、diffがない場合は空文字列で返ってくるので、次のように書いていきます。
if diff := cmp.Diff(res, expected); diff != "" {
t.Errorf("Hogefunc differs: (-got +want)\n%s", diff)
}
実際に差分があった場合は次のようなテスト結果が表示されます。
=== RUN TestFuncHoge
--- FAIL: TestFuncHoge (0.00s)
main.go:56: Hogefunc differs: (-got +want)
{Hoge}.AnotherStruct.Moji:
-: "hugahuga"
+: "hugahuga_diff"
FAIL
とても見やすいですね。
その他
オプションも付けれるので詳しく設定されたい方は次のExampleを参照してみてください。