英文:
Gomock not returning the expected value
问题
我是一名经验丰富的程序员,但对Go语言还不熟悉。我正在编写一些日志测试,并为此目的生成了一个LogSink类的模拟对象(使用mockgen)。由于那部分是自动生成的,我认为我们可以假设没有什么异常情况。
以下是我的测试代码:
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")
}
但是这个测试失败了,因为"Foo"日志从未被调用。我逐步调试了代码,并发现我的EXPECT().Do()代码按预期被调用,并返回true,但在模拟代码内部,它将Logger.sink.Enabled()的结果视为false!
我做错了什么?我是否漏掉了某个秘密开关?
英文:
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?
答案1
得分: 0
嗯,事实证明,.Do() 有意地 忽略返回值。以下是代码中的文档说明:
// Do声明了在调用匹配时要运行的操作。为了保持向后兼容性,函数的返回值被忽略。要使用返回值,请调用DoAndReturn。
向后兼容性。是的,如果你问我,这真是个公共领域里的可恶陷阱...
英文:
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...
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论