apitest
Mocks

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()
MethodMatches 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()
MethodMatches 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()
MethodMatches 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()
MethodMatches 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()
MethodMatches 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.

On this page