Custom matchers
Add your own matching logic, or match JSON bodies with JSONPath.
AddMatcher adds a matcher alongside the built-in ones. It receives the outbound request and the mock's request specification, and returns an error when the request should not match. The error message is shown in debug output.
getPreferences := apitest.NewMock().
Get("/api/preferences/1234").
AddMatcher(func(r *http.Request, mr *apitest.MockRequest) error {
if r.URL.Scheme != "https" {
return errors.New("expected an https request")
}
return nil
}).
AddMatcher(hasRequestID).
RespondWith().
Status(http.StatusOK).
End()type Matcher func(*http.Request, *apitest.MockRequest) errorMatchers are values, so they can be named and shared:
// hasRequestID matches requests that carry a UUID request id.
var hasRequestID apitest.Matcher = func(r *http.Request, _ *apitest.MockRequest) error {
id := r.Header.Get("X-Request-Id")
if len(id) != 36 || strings.Count(id, "-") != 4 {
return errors.New("expected X-Request-Id to be a UUID")
}
return nil
}
Reading the body
A matcher that reads r.Body must replace it afterwards, for example with io.NopCloser(bytes.NewReader(b)), so later matchers, the other mocks and debug output can still read it.
JSONPath matchers
The mocks package of apitest-jsonpath provides matchers for JSON request bodies. They match part of the body, which suits payloads that contain IDs or timestamps.
import "github.com/steinfletcher/apitest-jsonpath/mocks"createAdmin := apitest.NewMock().
Post("http://users/api/user").
AddMatcher(mocks.Equal(`$.name`, "jon")).
AddMatcher(mocks.Contains(`$.roles`, "admin")).
AddMatcher(mocks.Len(`$.roles`, 2)).
RespondWith().
Status(http.StatusCreated).
End()| Matcher | Matches when |
|---|---|
mocks.Equal(expr, v) | The expression selects a value equal to v. |
mocks.NotEqual(expr, v) | The expression selects a value not equal to v. |
mocks.Contains(expr, v) | The expression selects an array that contains v. |
mocks.Len(expr, n) | The selected value has length n. |
mocks.GreaterThan(expr, n) | The selected value has length of at least n. |
As with the assertions, JSON numbers decode as float64.