Ramil Kuvatov
Ramil Kuvatov

Reputation: 43

gomock 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?

Upvotes: 3

Views: 21901

Answers (4)

antonbiz
antonbiz

Reputation: 31

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.

Upvotes: 3

TaQuangTu
TaQuangTu

Reputation: 2343

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()

Upvotes: 10

Robin
Robin

Reputation: 613

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.

enter image description here

Upvotes: 3

Noah Stride
Noah Stride

Reputation: 486

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 ?

Upvotes: 2

Related Questions