I'm running a test with multiple parameters in a for loop using go lang testing.
I ran into a situation where same return value (and first set) is returned every time the mock is called. What I want to be able to do is change the return value for each test when the input is same i.e., same On
but different Return
in a loop.
I am using stretchr/testify for mocks. It looks like it will not overwrite already created mock when On
is same.
func TestUpdateContactWithNewActions(t *testing.T) {
tests := []struct {
testName string
getParams func() *activities.UpdateContactWithNewActionsActivity
mockError error
}{
{"UpdateContactWithNewActions with error from contact service",
func() *activities.UpdateContactWithNewActionsActivity {
return fixtures.GetUpdateContactWithNewActionsActivity()
}, fixtures.Err},
{"UpdateContactWithNewActions valid",
func() *activities.UpdateContactWithNewActionsActivity {
return fixtures.GetUpdateContactWithNewActionsActivity()
}, nil},
}
lib.LoadWithMockClients()
for _, test := range tests {
test := test
t.Run(test.testName, func(t *testing.T) {
lib.MockCSClient.On(
"UpdateContactWithNewActions",
mock.AnythingOfType("tchannel.headerCtx"),
fixtures.UpdateContactWithNewActions).Return(test.mockError)
returnedResult, err := test.getParams().Execute(fixtures.Ctx)
if test.mockError == nil {
// some assertion
}
assert.Error(t, err)
})
}
}
I had a similar problem.
The solution was the method Once()
In your mock add an .Once()
and repeat the mock with each result you need.
Something like this:
lib.Mock.On("method", arg).Return(test.mockError).Once()
lib.Mock.On("method", arg).Return(nil).Once()
Each mock result will be returned only once.
https://godoc.org/github.com/stretchr/testify/mock#Call.Once
The answer @Marcos provided works well when the result needs to be returned exactly once.
But in the scenario where each return value needs to be returned multiple (unknown) times, it won't work.
The way I solved it is by manipulating the mock.ExpectedCalls
directly. In my case the mock was holding only a single method, so it was simple to just cleanup the whole ExpectedCalls
slice, but in case there are multiple methods, the ExpectedCalls
slice can be iterated, and update only the required call.
here is a working example for the simple case:
lib.Mock.On("method", arg).Return("1")
assert.Equal(t, lib.Mock.method(arg), "1")
assert.Equal(t, lib.Mock.method(arg), "1")
....
assert.Equal(t, lib.Mock.method(arg), "1")
lib.Mock.ExpectedCalls = nil // cleanup the previous return value
lib.Mock.On("method", arg).Return("2")
assert.Equal(t, lib.Mock.method(arg), "2")
assert.Equal(t, lib.Mock.method(arg), "2")
....
assert.Equal(t, lib.Mock.method(arg), "2")
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With