Defining mocks
Build a mock in two halves, the request to match and the response to return.
apitest.NewMock() starts a mock. A method such as Get sets the request to match, RespondWith() switches to the response, and End() finishes the mock:
createUser := apitest.NewMock().
Post("https://users/api/user").
Header("Authorization", "Bearer .+").
Query("notify", "true").
JSON(`{"name": "jon"}`).
RespondWith().
Status(http.StatusCreated).
JSON(`{"id": "1234", "name": "jon"}`).
End()Pass mocks to the test with Mocks, which takes any number of them:
apitest.New().
Mocks(getUser, getPreferences).
Handler(handler).
Get("/user/1234").
Expect(t).
Status(http.StatusOK).
End()Calling Mocks again replaces the earlier list, so pass every mock in one call.
The request
The verb methods set the method and URL to match:
| Method | Matches |
|---|---|
Get, Post, Put, Patch, Delete, Head | The method and URL. |
Getf, Postf, Putf, Patchf, Deletef | The method and a URL formatted with fmt.Sprintf. |
Method(method) | Any method, such as OPTIONS. Set the URL with URL or URLf, or leave it out to match any URL. |
The URL's path is matched as a regular expression, and its scheme and host are matched when present. See how matching works.
preflight := apitest.NewMock().
Method(http.MethodOptions).
URL("http://users/api/user").
RespondWith().
Status(http.StatusNoContent).
End()The request side then accepts matchers for headers, query parameters, the body, form data, cookies and basic auth, plus custom matchers.
The response
After RespondWith(), set what the mock returns. See responses.
Always set a status
A mock without Status responds with status code 0, which is rarely what the code under test expects.
Sharing mocks
Mocks are values, so they can be declared once as package variables and reused by many tests:
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()
A test copies the mocks it receives before counting calls, so the call count of a shared mock starts fresh in every test.