Тестирование с Gomock возвращает ошибку: ожидаемый вызов уже был вызван максимальное количество раз - PullRequest
0 голосов
/ 06 июля 2018

Я использую 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 Ответ

0 голосов
/ 06 июля 2018

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

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

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

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