How to mock http.Client Do method

Any struct with a method matching the signature you have in your interface will implement the interface. For example, you could create a struct ClientMock

type ClientMock struct {
}

with the method

func (c *ClientMock) Do(req *http.Request) (*http.Response, error) {
    return &http.Response{}, nil
}

You could then inject this ClientMock struct into your GetOverview func. Here's an example in the Go Playground.


The net/http/httptest package is your best friend:

// generate a test server so we can capture and inspect the request
testServer := httptest.NewServer(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) {
    res.WriteHeader(scenario.expectedRespStatus)
    res.Write([]byte("body"))
}))
defer func() { testServer.Close() }()

req, err := http.NewRequest(http.MethodGet, testServer.URL, nil)
assert.NoError(t, err)

res, err := http.DefaultClient.Do(req)
assert.NoError(t, err)
assert.Equal(t, scenario.expectedRespStatus, res.StatusCode, "status code should match the expected response")

You have to create a struct with methods that match interface. Mocks are commonly used for testing purposes, therefore people want the ability to prepare return values of mock methods. To achieve this, we create struct with func attributes corresponding to methods.

As your interface is:

type HttpClient interface {
    Do(req *http.Request) (*http.Response, error)
}

Equivalent mock:

type MockClient struct {
    DoFunc func(req *http.Request) (*http.Response, error)
}

func (m *MockClient) Do(req *http.Request) (*http.Response, error) {
    if m.DoFunc != nil {
        return m.DoFunc(req)
    }
    return &http.Response{}, nil
}

Then, next step is to write some tests. Example here.


I know it's been a little while but I just wrote something to help with this recently.

Generally to mock HTTP requests I recommend starting up a real HTTP server locally, since in Go this is easy to do. https://golang.org/pkg/net/http/httptest/ is a pretty standard way to do that (see the example code given under the Server type).

However having done a lot of HTTP mocking I wanted something that does a little more, like a good mock library would: easy setting of expectations, validation that all requests were made, etc. I have generally used https://godoc.org/github.com/stretchr/testify/mock for mocking and wanted features like that.

So I wrote https://github.com/dankinder/httpmock, which basically combines the two.