apitest

Anatomy of a test

Every apitest test has three parts, configuration, request and expectations, built in one chain.

user_test.go
func TestGetUser(t *testing.T) {
	apitest.New("gets a user").
		// 1. configuration
		Mocks(getUserMock, getPreferencesMock).
		Handler(newUserAPI()).
		// 2. request
		Get("/user/1234").
		// 3. expectations
		Expect(t).
		Status(http.StatusOK).
		Body(`{"id": "1234", "name": "jon", "is_contactable": true}`).
		End()
}

1. Configuration

apitest.New starts a test. The optional name appears in reports. Configuration methods return the test, so they can be chained in any order:

MethodPurpose
Handler, HandlerFuncThe handler under test. See requests.
MocksAnswers for the outbound HTTP calls the handler makes. See mocks.
HttpClientReplace the transport of your own http.Client instead of http.DefaultClient.
Report, Recorder, MetaRender the test as a sequence diagram or a custom report.
DebugPrint every request and response on the wire. See debugging.
Observe, ObserveMocksHooks that receive the final and mocked requests and responses.
InterceptChange the built request before it is sent. See intercept.
EnableNetworkingSend the request over the network to a running server. See end-to-end tests.
EnableMockResponseDelayHonour FixedDelay on mocks. See failures and latency.
VerifierReplace the assertion implementation. See test frameworks.
UseFS, HostThe file system for multipart uploads, and the request Host.

apitest.Handler(h) and apitest.HandlerFunc(f) are shorthand for apitest.New().Handler(h) when no other configuration is needed.

The mocks in the example are package variables, so several tests can share them:

mocks_test.go
var getUserMock = apitest.NewMock().
	Get("http://users/api/user/1234").
	RespondWith().
	Status(http.StatusOK).
	Body(`{"id": "1234", "name": "jon"}`).
	End()

var getPreferencesMock = apitest.NewMock().
	Get("http://preferences/api/preferences/1234").
	RespondWith().
	Status(http.StatusOK).
	JSON(map[string]any{"is_contactable": true}).
	End()

2. Request

A method such as Get, Post or Method ends the configuration and starts the request. The request builder sets headers, query parameters, cookies, the body and so on. See building requests.

3. Expectations

Expect(t) ends the request and starts the expectations. It takes the *testing.T, or anything that satisfies apitest.TestingT.

The expectation builder asserts on the status, headers, cookies and body, and accepts custom assertions. End() runs the test and returns a Result.

Remember to call End()

Nothing runs until End() is called. A chain that stops at an expectation compiles, makes no request, and passes.

The application in these docs

Most examples test a small user API. GET /user/{id} fetches the user from a users service and their contact preferences from a preferences service, then combines the two. Both services are called over HTTP with http.DefaultClient.

On this page