type fnmatcher struct {
d func(x interface{}) bool
desc string
}
func (self *fnmatcher) Matches(x interface{}) bool {
return self.d(x)
}
func (self *fnmatcher) String() string {
return self.desc
}
func On(desc string, d func(x interface{}) bool) mock.Matcher {
return &fnmatcher{d: d, desc: desc}
}
// TestSendOverdueMessages_ok is an example of using matching using a callback function
func TestSendOverdueMessages_ok(t *testing.T) {
ctrl := mock.NewController(t)
defer ctrl.Finish()
mockUserRepo := NewMockUserRepository(ctrl)
mockMessageRepo := NewMockMessageRepository(ctrl)
mockMessageSender := NewMockMessageSender(ctrl)
log, _ := NewBufferLog()
r := NewPastSelfService(
mockMessageRepo,
mockMessageSender,
mockUserRepo,
log,
)
senderUserDDB_1 := &UserDDB{UserID: "sender1"}
senderUserDDB_2 := &UserDDB{UserID: "sender2"}
recipientUserDDB_2 := &UserDDB{
UserID: "recipient2",
Profile: UserProfileDDB{
PreferredEmail: "recipient2@example.com",
},
}
resultSet := &ResultSet{
Items: []Message{
{
ID: 1,
SenderID: "sender1",
Body: "body1",
Recipients: []string{"email://recipient1@example.com", "recipient2"},
Headers: []Header{
{Name: "x-header-key-1", Value: "value-1"},
{Name: "x-header-key-2", Value: "value-2"},
},
},
{
ID: 2,
SenderID: "sender2",
Body: "body2",
},
},
}
mockUserRepo.EXPECT().GetUser("sender1").Return(senderUserDDB_1, nil)
mockUserRepo.EXPECT().GetUser("sender2").Return(senderUserDDB_2, nil)
mockUserRepo.EXPECT().GetUser("recipient2").Return(recipientUserDDB_2, nil)
mockMessageRepo.EXPECT().FindOverdue(mock.Any(), 0, "").Return(resultSet, nil)
matchFrom := On("user.UserID==sender1", func(x interface{}) bool {
if y, ok := x.(*UserDDB); ok {
return y.UserID == "sender1"
}
return false
})
matchTo := On("[]Recipient{recipient1@example.com,recipient2@example.com}", func(x interface{}) bool {
if y, ok := x.([]Recipient); ok {
return len(y) == 2 &&
y[0].Email == "recipient1@example.com" &&
y[1].Email == "recipient2@example.com"
}
return false
})
matchOutMessage := On("OutboundMessage.Body==Body1", func(x interface{}) bool {
if y, ok := x.(OutboundMessage); ok {
return y.Body == "body1"
}
return false
})
mockMessageSender.EXPECT().Send(matchFrom, matchTo, matchOutMessage).Return(nil).MaxTimes(1)
r.SendOverdueMessages()
}
One thing nice about GoMock is that it generates statically typed method names for the EXPECT()
statements, so the
compiler can check that you’re using the correct method names. Neat.