I'm an experienced programmer but new to Go. I'm writing some logging tests, and for these purposes I've generated a mock of the LogSink
class (using mockgen
). Since that part is all auto-generated, I think we can assume nothing untoward there.
So here is my test code:
func TestLogging(t *testing.T) {
ls := mock.NewMockLogSink(gomock.NewController(t))
ls.EXPECT().Init(gomock.Any())
const logLevel = 1
ls.EXPECT().Enabled(gomock.Any()).AnyTimes().Do(func(level int) bool {
return level <= logLevel
})
log.Set(logr.New(ls))
ls.EXPECT().Info(gomock.Any(), "Foo").Times(1)
log.Info("Foo")
ls.EXPECT().Info(gomock.Any(), "Bar").Times(0)
log.V(2).Info("Bar")
}
But this test fails, because the "Foo" log never gets called. I stepped through the code and found that my EXPECT().Do()
code is being called as expected, and is returning true
, but inside the mock code, it sees the result of Logger.sink.Enabled()
as false
!
What am I doing wrong? Is there a secret switch I'm missing?
CodePudding user response:
Well, it turns out .Do()
intentionally ignores return values. Here's the documentation from the code:
// Do declares the action to run when the call is matched. The function's
// return values are ignored to retain backward compatibility. To use the
// return values call DoAndReturn.
Backward compatibility. Right. Bloody pit in the public domain, if you ask me...