Reputation: 3772
I would like to Mock the response of a function. But this function is located or called inside another function. Let say I have this function
// main.go
func TheFunction() int {
// Some code
val := ToMockResponse()
return val
}
func ToMockResponse() int {
return 123
}
Now on my test file
// main_test.go
func TestTheFunction(t *testing.T) {
mockInstance = new(randomMock)
mockInstance.On("ToMockResponse").Return(456)
returned := TheFunction()
assert.Equal(t, 456, returned)
}
As you can see within function TheFunction() a call to function ToMockResponse is made. Now I would like to test TheFunction but I would like to Mock the response of ToMockResponse how can I achieve this?
Upvotes: 3
Views: 3258
Reputation: 742
Let's consider we have two functions, executor()
and process()
where executor function calls process function,
We need to write both the functions as shown below with structures and interfaces:
main.go
is as shown below:
package main
import "fmt"
// A structure defined which will have a value of type processHandler(interface)
// This is helpful to pass a structure instance of processData later(see in main function)
// This is required to pass mock instance also
type processDataHandler struct{ procData processHandler }
// Interface defined for process method
type processHandler interface {
process() (int, string)
}
// structure on top of which executor method is getting called
type processData struct{}
// process method called by executor method
func (p processData) process() (int, string) {
return 23, "test2"
}
// executor method which has "processDataHandler" as argument
func (e processDataHandler) executor() (int, string) {
// Some code
//process function call
val, str_val := e.procData.process()
if val == 23 {
return 40, "success"
}
return 45, str_val
}
func main() {
procData := processData{}
dataHandle := processDataHandler{procData: procData}
val1, val2 := dataHandle.executor()
fmt.Println(val1)
fmt.Println(val2)
}
main_test.go
is as shown below:
package main
import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
)
//Define a mock insatnce
type processDataMock struct {
mock.Mock
}
func (m *processDataMock) process() (int, string) {
// this records that the method was called and passes in the value
// it was called with
args := m.Called()
// it then returns whatever we tell it to return
// in this case we are returing a integer type followed by a string type
return args.Int(0), args.String(1)
}
//Test function for executor method
func TestExecutor(t *testing.T) {
//define mock instance
procMock := new(processDataMock)
//Make process function to return 1 and "test" via mock
procMock.On("process").Return(1, "test")
//create a processDatahandler with mock instance
handler := processDataHandler{procData: procMock}
//call executor function which inturn mocks process via "procMock.On" above
a, b := handler.executor()
assert.Equal(t, 45, a)
assert.Equal(t, "test", b)
}
Upvotes: 0
Reputation: 1804
You should consider passing in the second function is as an parameter to the first.
You have a few options for doing that. You could simply pass it as a parameter.
func DoX(doY func()) {
doY()
}
That’s simple but doesn’t work well as the core get more complex. The better alternative is often to make the functions methods on a struct.
type X struct {
Y Y
}
type Y interface {
Do()
}
func (x *X) Do() {
x.Y.Do()
}
Then Y can be replaced with a mock.
Upvotes: 1