Consider a function with a key/value database dependency:
type DB interface {
Get(key string) string
Set(key string, value string)
}
func ContrivedFunction(db DB) string {
db.Set("key", "value")
return db.Get("key")
}
And let's test it using mockery: func TestContrivedFunction(t *testing.T) {
db := mocks.NewDB(t)
if ContrivedFunction(db) != "value" {
t.Error("unexpected result")
}
}
Code looks reasonable enough, but then... Epic failure. This should work, at least it should if `db` is a mock. But it does not work. `db` deceived us. Clearly not a mock in any sense of the word.But, okay. It is still something. We will play its game:
func TestContrivedFunction(t *testing.T) {
db := mocks.NewDB(t)
db.Mock.On("Set", "key", "value").Return()
db.Mock.On("Get", "key").Return("value")
if ContrivedFunction(db) != "value" {
t.Error("unexpected result")
}
}
Wonderful. We're back in business. Tests are passing and everything is sunshine and rainbows.But now, the contrived project manager just called and, for contrived reasons, would like to change the organization of record keys:
func ContrivedFunction(db DB) string {
db.Set("ns:key", "value")
return db.Get("ns:key")
}
Ah, fuck! The test just broke again. But it shouldn't have. The utility of ContrivedFunction – that which is under test – hasn't changed one bit. The DB implementation should have been able to handle this just fine. The DB implementation used in production handles this just fine. This mockery tool is fundamentally broken.But not only is it broken, it doesn't seem to serve a purpose. Why would you even use it?