gomock缺少调用(s)。

huangapple go评论71阅读模式
英文:

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()但没有调用它。

gomock缺少调用(s)。

英文:

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.

gomock缺少调用(s)。

答案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().&lt;interface-method&gt;().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.

huangapple
  • 本文由 发表于 2021年8月16日 01:49:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/68794050.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定