英文:
gomock missing call(s)
问题
我正在尝试使用gomock来模拟下面的方法:
func (w *writer) Publish(vacancies []model.Vacancy) error {
...
if _, err = w.conn.WriteMessages(msg); err != nil {
return fmt.Errorf("failed to write message: %w", err)
}
}
接口:
type Producer interface {
Publish(vacancies []model.Vacancy) error
Close() error
}
测试套件:
func (p *ProducerTestSuite) SetupTest() {
p.mockCtrl = gomock.NewController(p.T())
p.producer = NewMockProducer(p.mockCtrl)
writer, err := producer.NewWriter(context.Background(), scheduler.KafkaConf{Addr: "localhost:9092", Topic: "test"})
p.Require().NoError(err)
p.writer = writer
}
...
func (p *ProducerTestSuite) TestProducer_Publish() {
p.producer.EXPECT().Publish([]model.Vacancy{}).Return(nil)
p.Require().NoError(p.writer.Publish([]model.Vacancy{}))
}
mockgen:
//go:generate mockgen -package producer_test -destination mock_test.go -source ../kafka.go
当我尝试运行测试时,我得到了以下消息:
=== RUN TestSuite/TestProducer_Publish
controller.go:137: missing call(s) to *producer_test.MockProducer.Publish(is equal to [] ([]storage.Vacancy)) /Users/...
controller.go:137: aborting test due to missing call(s)
我错在哪里了?
英文:
I am trying to mock the below method using gomock
func (w *writer) Publish(vacancies []model.Vacancy) error {
...
if _, err = w.conn.WriteMessages(msg); err != nil {
return fmt.Errorf("failed to write message: %w", err)
}
Interface:
type Producer interface {
Publish(vacancies []model.Vacancy) error
Close() error
}
SuiteTest:
func (p *ProducerTestSuite) SetupTest() {
p.mockCtrl = gomock.NewController(p.T())
p.producer = NewMockProducer(p.mockCtrl)
writer, err := producer.NewWriter(context.Background(), scheduler.KafkaConf{Addr: "localhost:9092", Topic: "test"})
p.Require().NoError(err)
p.writer = writer
}
...
func (p *ProducerTestSuite) TestProducer_Publish() {
p.producer.EXPECT().Publish([]model.Vacancy{}).Return(nil)
p.Require().NoError(p.writer.Publish([]model.Vacancy{}))
}
mockgen:
//go:generate mockgen -package producer_test -destination mock_test.go -source ../kafka.go
When I try run test, I got this message:
=== RUN TestSuite/TestProducer_Publish
controller.go:137: missing call(s) to *producer_test.MockProducer.Publish(is equal to [] ([]storage.Vacancy)) /Users/...
controller.go:137: aborting test due to missing call(s)
Where I wrong?
答案1
得分: 4
这个答案有点晚,但可能会有帮助。
要求函数只被调用一次:
mockService.EXPECT().DoSomething().Return(nil, nil)
允许函数被调用零次或多次:
mockService.EXPECT().DoSomething().Return(nil, nil).AnyTimes()
英文:
This answer is late, but it might helpful.
To require the function to be called once:
mockService.EXPECT().DoSomething().Return(nil, nil)
To allow the function to be called zero or more times:
mockService.EXPECT().DoSomething().Return(nil, nil).AnyTimes()
答案2
得分: 2
Expect()表示这些必须是对该方法的调用,并且参数必须符合指定的要求,否则将失败。缺少调用意味着你设置了Expect()但没有调用它。
英文:
the Expect() means these must be a call to this method with the specified parameter, otherwise it will be failed, the missing call means your set a Expect() but didn't call it.
答案3
得分: 1
看起来你在调用的时候并没有调用你期望的东西。你的期望是在观察 p.producer.Publish()
,但是你的测试代码调用的是 p.writer.Publish()
。我在这里看不到任何代码会导致 writer
调用 producer
中的任何内容。
下面的代码将按照你的期望行为运行:
func (p *ProducerTestSuite) TestProducer_Publish() {
p.producer.EXPECT().Publish([]model.Vacancy{}).Return(nil)
p.Require().NoError(p.producer.Publish([]model.Vacancy{}))
}
然而,这个测试似乎并没有实际测试到测试名称所指示的单元。也许你对模拟有误解?
英文:
It appears as if you are not calling the same thing that you are expecting on. Your expect is watching p.producer.Publish()
, but your test code calls p.writer.Publish()
. I cannot see any code here that would lead writer
to call anything in producer
.
The following code would behave as you expect:
func (p *ProducerTestSuite) TestProducer_Publish() {
p.producer.EXPECT().Publish([]model.Vacancy{}).Return(nil)
p.Require().NoError(p.producer.Publish([]model.Vacancy{}))
}
However, this test does not seem to actually exercise the unit that the test name indicates it should. Perhaps you are misunderstanding mocking ?
答案4
得分: 1
我也通过添加以下代码解决了类似的问题:
EXPECT().<interface-method>().Return(...).AnyTimes()
看起来,如果设置了EXPECT(),gomock会假设它必须至少被调用一次。添加AnyTimes()可以允许它被调用0次。
英文:
I also resolved a similar issue by adding a:
EXPECT().<interface-method>().Return(...).AnyTimes()
It seems that if one sets an EXPECT() gomock assumes that it must be called at least once. Adding AnyTimes() allows it to be called 0 times.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论