gomockの引数のMatcherでgomock.Eq()
を使うときに、構造体がポインタ型だったりするとうまく比較できない。
type Hoge struct { ID string } m.EXPECT().Hoge(gomock.Eq(&Hoge{ID: "1"})).Return(nil).AnyTimes() // マッチしない m.Hoge(&Hoge{ID: "1"})
そのため、go-cmp を使って両者を比較するカスタムMatcherを実装する。
func GomockDeepEq(expected interface{}) gomock.Matcher { return &gomockDeepEqMatcher{ expected: expected, } } type gomockDeepEqMatcher struct { expected interface{} diff string } func (m *gomockDeepEqMatcher) Matches(x interface{}) bool { m.diff = cmp.Diff(x, m.expected, CmpTransformJSON()) return m.diff == "" } func (m *gomockDeepEqMatcher) String() string { return m.diff } // interface check var _ gomock.Matcher = (*gomockDeepEqMatcher)(nil)
type Hoge struct { ID string } m.EXPECT().Hoge(GomockDeepEq(&Hoge{ID: "1"})).Return(nil).AnyTimes() // マッチする m.Hoge(&Hoge{ID: "1"})
ここで、 go-cmp の cmp.Diff() でJSON文字列を比較できるようにする - mrk21::blog {} で述べたように、JSON文字列を比較できるようにしておくとさらに便利になる。
type Hoge struct { ID string JSON json.RawMessage } m.EXPECT().Hoge(GomockDeepEq(&Hoge{ID: "1", JSON: json.RawMessage(`{"a":1, "b":2}`)})).Return(nil).AnyTimes() // マッチする m.Hoge(&Hoge{ID: "1", JSON: json.RawMessage(`{"b":2, "a":1}`)})
環境
- Go:
1.9.3
- gomock:
1.4.4
- go-cmp:
0.5.9