Stubbing out the Go http.Client
to test an HTTP HandlerFunc
If you're writing Go tests that interact with an API, at some point you'll want to fully test your built API, but don't necessarily want to have the server actually running + interacting with real dependencies.
For instance, you may be wanting to use a generated OpenAPI client, but want to test it against your configured server's ServeHTTP
function instead of executing the service for real.
Note that this is a separate set of testing to just testing the handlers in isolation, where we'd be able to unit test just those method calls. In this version, we're testing that the fully configured router works as expected, with i.e. an OpenAPI client.
It's actually pretty straightforward by taking advantage of Go's httptest
package, and interface types, which allow us to write the following:
import (
"context"
"fmt"
"net/http"
"net/http/httptest"
"testing"
"github.com/gorilla/mux"
// this would also include the `api` package, which is expected to contain the `oapi-codegen`'d API client
)
type server interface {
ServeHTTP(w http.ResponseWriter, r *http.Request)
}
type fakeClient struct {
server server
}
func (c *fakeClient) Do(r *http.Request) (*http.Response, error) {
rr := httptest.NewRecorder()
c.server.ServeHTTP(rr, r)
return rr.Result(), nil
}
func TestRouter(t *testing.T) {
var server server
// construct the server i.e. by `mux.NewRouter()`
fakeClient := fakeClient{
server: server,
}
client, err := api.NewClientWithResponses("", api.WithHTTPClient(&fakeClient))
resp, err := client.Healthcheck(context.TODO())
if err != nil {
t.Errorf(err.Error())
}
if 200 != resp.StatusCode {
t.Errorf("Expected status code 200, but was %d", resp.StatusCode)
}
}