Тестирование и насмешка над функцией, которая не возвращает никакого значения

Я хочу протестировать функцию, которая не возвращает никакого значения, а вместо этого запускает другие функции. Читая о тестировании, я нашел информацию о том, что это называется поведенческой проверкой, и что с помощью насмешек я могу проверить, какие функции и в каком порядке срабатывают. Однако у меня есть проблема с реализацией правильной техники для моего кода.

Давайте рассмотрим простой пример следующего интерфейса и структуры (этот пример очень прост для упрощения объяснения):

type ExampleInterface interface {
    DoSomething(arg int)
    DoEvenMore(arg int)
    AndEvenMore(arg int)
} 

type ExampleStruct struct {
     Id string 
     // Other fields
}

func (e *ExampleStruct) DoSomething(arg int) {
     arg2 := arg * 2
     e.DoEvenMore(arg2)
     arg3 := arg * 3
     e.AndEvenMore(arg3)  
}

func (e *ExampleStruct) DoEvenMore(arg int){
     fmt.Println("I did so many operations here using ", arg)
}

func (e *ExampleStruct) AndEvenMore(arg int) {
     // Performing other operations on arg
}

Теперь я хочу проверить функцию DoSomething, Поскольку он не возвращает никакого значения, я хочу проверить, происходит ли после вызова этой функции с аргументом 3 следующая цепочка событий: функция DoEvenMore вызывается один раз с аргументом 6и следующая функция AndEvenMore вызывается один раз с аргументом 9

Я написал следующий тест:

func TestDoSomething(t *testing.T) {

    mockCtrl := gomock.NewController(t)
    defer mockCtrl.Finish()

    mockClient := mocks.NewMockExampleInterface(mockCtrl)

    example := ExampleStruct("ExampleId")

    gomock.InOrder(
        mockClient.EXPECT().DoSomething(3).Return().Times(1)
        mockClient.EXPECT().DoEvenMore(6).Return().Times(1)
        mockClient.EXPECT().AndEvenMore(9).Return().Times(1) 
    )

    example.DoSomething(3)
}

Однако, когда я запускаю этот тест, я получаю ошибку: Unexpected call to *mocks.MockExampleInterface.DoSomething(..),

Как мне правильно выполнить насмешку в таком примере?

1 ответ

Решение

Два метода, вызываемые DoSomething являются конкретными реализациями, вы не можете издеваться над чем-то подобным в Go.

Чтобы достичь того, что вы хотите DoSomething будет зависеть от интерфейса, который определяет эти два метода и вызывает их вместо конкретных.

type DoMorer interface {
    DoEvenMore(arg int)
    AndEvenMore(arg int)
} 

type ExampleStruct struct {
     Id string 
     // Other fields
}

func (e *ExampleStruct) DoSomething(arg int, dm DoMorer) {
     arg2 := arg * 2
     dm.DoEvenMore(arg2)
     arg3 := arg * 3
     dm.AndEvenMore(arg3)  
}

При такой настройке во время тестирования вы можете создать макет для DoMorer интерфейс и передать это DoSomething,


DoMorer не нужно передавать в качестве аргумента, это может быть поле ExampleStruct или глобальный, все, что соответствует вашим потребностям.

Другие вопросы по тегам