Тестирование с Gomock возвращает ошибку: ожидаемый вызов уже был вызван максимальное количество раз

Я использую Gomock https://godoc.org/github.com/golang/mock и mockgen

Исходный код этого теста:

package sqs

import (
    "fmt"
    "log"
    "os"
    "runtime"

    "github.com/aws/aws-sdk-go/aws/session"

    "github.com/aws/aws-sdk-go/aws"
    "github.com/aws/aws-sdk-go/service/sqs"
    "github.com/aws/aws-sdk-go/service/sqs/sqsiface"
)

var sess *session.Session
var svc *sqs.SQS
var queueURL string

func init() {
    // Setting the runtime to run with max CPUs available
    runtime.GOMAXPROCS(runtime.NumCPU())

    sess = session.Must(session.NewSessionWithOptions(session.Options{
        SharedConfigState: session.SharedConfigEnable,
    }))

    svc = sqs.New(sess)

    queueURL = os.Getenv("QUEUE_URL")
}

type Poller interface {
    Poll(chan bool)
}

// NewPoller is a factory to create a Poller object
func NewPoller(msgr Messenger) Poller {
    p := &poller{
        m: msgr,
    }
    return p
}

type poller struct {
    m Messenger
}

func (p *poller) Poll(done chan bool) {
    sqsMsgCh := make(chan *sqs.Message, 100)
    for {
        messages, err := p.m.GetMessage()
        if err != nil {
            log.Printf("error when getting message")
            if len(messages) == 0 {
                // Stop the system
                log.Printf("I am here")
                done <- true
            }
        }
        for _, msg := range messages {
            sqsMsgCh <- msg
        }
    }
}

type Messenger interface {
    GetMessage() ([]*sqs.Message, error)
}

func NewMessenger() Messenger {
    return &messenger{
        s: svc,
    }
}

type messenger struct {
    s sqsiface.SQSAPI
}

func (m *messenger) GetMessage() ([]*sqs.Message, error) {
    result, err := m.s.ReceiveMessage(&sqs.ReceiveMessageInput{
        AttributeNames: []*string{
            aws.String(sqs.MessageSystemAttributeNameSentTimestamp),
        },
        MessageAttributeNames: []*string{
            aws.String(sqs.QueueAttributeNameAll),
        },
        QueueUrl:            aws.String(queueURL),
        MaxNumberOfMessages: aws.Int64(10),
        VisibilityTimeout:   aws.Int64(36000), // 10 hours
        WaitTimeSeconds:     aws.Int64(0),
    })

    if err != nil {
        fmt.Println("Error", err)
        return nil, err
    }

    msgs := result.Messages
    if len(msgs) == 0 {
        fmt.Println("Received no messages")
        return msgs, err
    }
    return msgs, nil
}

Тестовый пример для этого исходного файла находится здесь:

package sqs

import (
    "errors"
    "testing"

    "path_to_the_mocks_package/mocks"
    "github.com/golang/mock/gomock"

    "github.com/aws/aws-sdk-go/service/sqs"
)


func TestPollWhenNoMessageOnQueue(t *testing.T) {
    mockCtrl := gomock.NewController(t)
    defer mockCtrl.Finish()

    msgr := mocks.NewMockMessenger(mockCtrl)
    mq := make([]*sqs.Message, 1)
    err := errors.New("Mock Error")
    // msgr.EXPECT().GetMessage().Return(mq, err) //.Times(1)
    // msgr.GetMessage().Return(mq, err) //.Times(1)
    msgr.EXPECT().GetMessage().Return(mq, err)

    p := NewPoller(msgr)
    done := make(chan bool)
    go p.Poll(done)
    <-done
    t.Logf("Successfully done: %v", done)
}

Когда я запускаю тесты, я получаю следующую ошибку:

sqs \ controller.go: 150: неожиданный вызов *mocks.MockMessenger.GetMessage([]) в path_to_mocks_package/mocks/mock_messenger.go:38 потому что: ожидаемый вызов path_to_sqs_package/sqs/sqs_test.go:35 уже был назван максимальное количество раз. ПОТЕРПЕТЬ ПОРАЖЕНИЕ

Если я напишу свой собственный макет следующим образом, тестовый пример будет успешно выполнен:

type mockMessenger struct {
    mock.Mock
}

func (m *mockMessenger) GetMessage() ([]*sqs.Message, error) {
    msgs := make([]*sqs.Message, 0)
    err := errors.New("Error")
    return msgs, err
}

1 ответ

Решение

Вы неявно говорите Гомоку, что ожидаете только одного звонка.

msgr.EXPECT().GetMessage().Return(mq, err)

Добавление ряда Times на макет, позволяет вам возвращать эти значения более одного раза.

msgr.EXPECT().GetMessage().Return(mq, err).AnyTimes()
Другие вопросы по тегам