How do I mock a function that write result to it's argument in Go
Suppose I have a method below,
func DoSomething(result interface{}) error {
// write some data to result
return nil
}
so the caller can call DoSomething as following
result := &SomeStruct{}
err := DoSomething(result)
if err != nil {
fmt.Println(err)
} else {
fmt.Println("The result is", result)
}
Now I know how to use testify or some other mocking tools to mock the returns value (it's err here) by something like
mockObj.On("DoSomething", mock.Anything).Return(errors.New("mock error"))
My question is "how do i mock the result argument" in this kind of scenario?
Since result is not a return value but a argument, the caller calls it by passing a pointer of a struct, and the function modify it.
Just like what https://godoc.org/github.com/golang/mock/gomock#Call.SetArg do
I have the same question
I use mockery so that you can pass a function(instead of a particular value) to Return in which you can do whatever you want with the data you passed. For example:
mockObj.On("DoSomething", mock.Anything).Return(func(input *SomeStruct) error {
input.field = some_value
return errors.New("mock error")
})
Are you not able to pass in the argument through the second parameter of the On() function?
e.g. mockObj.On("DoSomething", resultInputArgument).Return(errors.New("mock error"))?
A bit late but you could also do a mock.MatchedBy
Something like:
mockObj.On("DoSomething", mock.MatchedBy(func(s *SomeType) bool {
s.field = some_value
return true
})).Return(nil)
I have the same question still unable to solve it.
This is what Run() is for, playground:
package main
import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
)
type MyStruct struct {
V string
}
type MyClass struct {
mock.Mock
}
func (m *MyClass) DoSomething(arg *MyStruct) error {
return m.Called(arg).Error(0)
}
func TestTestify(t *testing.T) {
s := &MyStruct{}
m := &MyClass{}
m.On("DoSomething", mock.AnythingOfType("*main.MyStruct")).Run(func(args mock.Arguments) {
arg := args.Get(0).(*MyStruct)
arg.V = "hello"
}).Return(nil)
err := m.DoSomething(s)
assert.NoError(t, err)
assert.Equal(t, "hello", s.V)
}
Do not use MatchedBy() to try to achieve this, it might be called more than once.