One minute
Mocking Native Http Go Client
If we have some Go code using http.Client
we might want to unit test it.
To do so we can create a new custom interface:
type Client interface {
Do(req *http.Request) (*http.Response, error)
}
Having this new interface we can easily prepare a mock, in this example I’ll use testify
:
type HTTPClientMock struct {
mock.Mock
}
Then we declare the method we want to mock, in our case Do
:
func (m *HTTPClientMock) Do(req *http.Request) (*http.Response, error) {
args := m.Called(req)
return args[0].(*http.Response), args.Error(1)
}
Then in our test we just have to create a new instance of that mock:
clientMock := new(HTTPClientMock)
We can use that mock to inject it to any service that requires http.Client
, and then with the following code we can set the expectation we want:
m.
On("Do", mock.MatchedBy(func(receivedReq *http.Request) bool {
assert.EqualValues(t, req.Method, receivedReq.Method, "invalid method")
assert.EqualValues(t, req.URL, receivedReq.URL, "invalid URL")
assert.EqualValues(t, req.Header, receivedReq.Header, "invalid header")
if "" == requestBody {
// if body is empty
assert.EqualValues(t, req.Body, receivedReq.Body, "invalid body")
} else {
// if we got some content
var err error
buf1 := new(bytes.Buffer)
_, err = buf1.ReadFrom(req.Body)
assert.NoError(t, err)
buf2 := new(bytes.Buffer)
_, err = buf2.ReadFrom(receivedReq.Body)
assert.NoError(t, err)
assert.JSONEq(t, buf1.String(), buf2.String(), "invalid JSON body")
}
return true
})).
Once().
Return(res, nil)