Request matchers
Match outbound requests on headers, query parameters, the body, form data, cookies and basic auth.
Matchers narrow down which requests a mock answers. They are set between the verb method and RespondWith(), and every one must pass for the mock to match.
Headers
getUser := apitest.NewMock().
Get("http://users/api/user/1234").
Header("Authorization", "^Bearer .+$").
Headers(map[string]string{"Accept": "application/json"}).
HeaderPresent("X-Request-Id").
HeaderNotPresent("X-Debug").
RespondWith().
Status(http.StatusOK).
End()| Method | Matches when |
|---|---|
Header(key, pattern) | A value of the header matches the regular expression. |
Headers(map[string]string) | Each entry matches as it would with Header. |
HeaderPresent(key) | The header exists, whatever its value. |
HeaderNotPresent(key) | The header does not exist. |
Query parameters
search := apitest.NewMock().
Get("http://search/api/users").
Query("q", "jon").
Query("page", `^\d+$`).
QueryParams(map[string]string{"sort": "asc"}).
QueryCollection(map[string][]string{"tag": {"a", "b"}}).
QueryPresent("page").
QueryNotPresent("debug").
RespondWith().
Status(http.StatusOK).
End()| Method | Matches when |
|---|---|
Query(key, pattern) | A value of the parameter matches the regular expression. |
QueryParams(map[string]string) | Each entry matches as it would with Query. |
QueryCollection(map[string][]string) | Each listed value matches a value of the parameter. |
QueryPresent(key) | The parameter exists. |
QueryNotPresent(key) | The parameter does not exist. |
Values are regular expressions, so Query("page", "1") also matches page=10. Anchor the pattern, as in ^1$, for an exact match.
Body
// exact string or equivalent JSON
byBody := apitest.NewMock().
Post("http://users/api/user").
Body(`{"name": "jon", "age": 32}`).
RespondWith().
Status(http.StatusCreated).
End()
// a value marshalled to JSON
byJSON := apitest.NewMock().
Post("http://users/api/user").
JSON(map[string]any{"name": "jon", "age": 32}).
RespondWith().
Status(http.StatusCreated).
End()
// a regular expression
byRegexp := apitest.NewMock().
Post("http://users/api/user").
BodyRegexp(`"name":\s*"jo.+"`).
RespondWith().
Status(http.StatusCreated).
End()| Method | Matches when |
|---|---|
Body(s) | The body equals s, or both are JSON and decode to equal values. |
Bodyf(format, args...) | As Body, with the expected body formatted by fmt.Sprintf. |
JSON(v) | As Body. Strings and byte slices are used as is, and other values are marshalled. |
BodyFromFile(path) | As Body, with the expected body read from a file. |
BodyRegexp(pattern) | The body matches the regular expression. |
createUser := apitest.NewMock().
Post("http://users/api/user").
BodyFromFile("testdata/create-user.json").
RespondWith().
Status(http.StatusCreated).
End()To match part of a JSON body, use the JSONPath matchers.
Form data
token := apitest.NewMock().
Post("http://auth/oauth/token").
FormData("grant_type", "client_credentials").
FormData("scope", "users:.*").
FormDataPresent("client_id").
FormDataNotPresent("client_secret").
RespondWith().
Status(http.StatusOK).
JSON(`{"access_token": "abc", "token_type": "Bearer"}`).
End()| Method | Matches when |
|---|---|
FormData(key, patterns...) | Each pattern matches a value of the field in the URL encoded body. |
FormDataPresent(key) | The field exists. |
FormDataNotPresent(key) | The field does not exist. |
Cookies and basic auth
invoices := apitest.NewMock().
Get("http://billing/api/invoices").
Cookie("session", "12345").
CookiePresent("tracking").
CookieNotPresent("legacy").
BasicAuth("billing-svc", "pa55word").
RespondWith().
Status(http.StatusOK).
End()| Method | Matches when |
|---|---|
Cookie(name, value) | A cookie with the name has exactly that value. |
CookiePresent(name) | A cookie with the name exists. |
CookieNotPresent(name) | No cookie with the name exists. |
BasicAuth(username, password) | The request carries exactly these basic auth credentials. |
Methods and URLs
Head matches HEAD requests, alongside Get, Post, Put, Patch and Delete:
logoExists := apitest.NewMock().
Head("http://cdn/assets/logo.png").
RespondWith().
Status(http.StatusOK).
Header("Content-Length", "2048").
End()Method matches any other method. Set the URL to match with URL, or with URLf to format it:
preflight := apitest.NewMock().
Method(http.MethodOptions).
URL("http://users/api/user").
RespondWith().
Status(http.StatusNoContent).
End()A mock started with Method and no URL matches every request with that method, whatever its scheme, host and path:
// without a URL, the mock matches every OPTIONS request
anyPreflight := apitest.NewMock().
Method(http.MethodOptions).
RespondWith().
Status(http.StatusNoContent).
AnyTimes().
End()URL and URLf were added in v1.7.0. On earlier versions, a mock built with Method and no URL panics when a request is matched against it.