apitest

End-to-end tests

Send requests over the network to a running server with EnableNetworking.

By default apitest calls the handler in process. EnableNetworking sends the request over the network instead, so the same builders can test a server running locally, in a container or in a staging environment.

client := &http.Client{Timeout: 5 * time.Second}

apitest.New().
	EnableNetworking(client).
	Get(baseURL + "/health").
	Expect(t).
	Status(http.StatusOK).
	End()
  • The URL must be absolute, including the scheme and host.
  • Pass a client to control timeouts, TLS and redirects. Without one, http.DefaultClient is used.
  • No handler is needed. A test without a handler and without networking fails.

Sessions

Each apitest test sends one request. A client with a cookie jar keeps cookies between tests, which models a browser session:

func TestLoginFlow(t *testing.T) {
	srv := httptest.NewServer(newSessionApp())
	defer srv.Close()

	// the cookie jar carries the session cookie between requests
	jar, _ := cookiejar.New(nil)
	client := &http.Client{Jar: jar, Timeout: 5 * time.Second}

	apitest.New().
		EnableNetworking(client).
		Post(srv.URL + "/login").
		Expect(t).
		Status(http.StatusNoContent).
		CookiePresent("session").
		End()

	apitest.New().
		EnableNetworking(client).
		Get(srv.URL + "/me").
		Expect(t).
		Status(http.StatusOK).
		Body(`{"name": "jon"}`).
		End()
}

Mocks and networking

Mocks replace a transport inside the test process. They cannot answer calls made by a server running in another process, so end-to-end tests run against real dependencies or the test doubles of that environment.

Keep mocks and networking apart in the same test. Mocks replace the transport of http.DefaultClient, or of the client given to HttpClient, so when the networking client is one of those, the request to the server is matched against the mocks instead of being sent.

httptest.Server

httptest.NewServer starts a real server on a free local port, which is useful to test behaviour that only happens over a real connection, such as TLS, HTTP/2 or connection handling. Most tests do not need it, because calling the handler in process is faster and covers the application logic.

On this page