# How matching works (/docs/mocks/matching)

## Order [#order]

For each outbound request, mocks are tried in the order they were passed to `Mocks`. The first mock whose matchers all pass answers the request. By default a mock answers one request and is then skipped, so mocks for the same URL answer successive calls in turn:

```go
// the first call fails, the next two succeed
unavailable := apitest.NewMock().
	Get("http://flaky/api/status").
	RespondWith().
	Status(http.StatusServiceUnavailable).
	End()

available := apitest.NewMock().
	Get("http://flaky/api/status").
	RespondWith().
	Status(http.StatusOK).
	Times(2).
	End()

apitest.New().
	Mocks(unavailable, available).
	Handler(handler).
	Get("/").
	Expect(t).
	Body("503,200,200").
	End()
```

[Call counts](/docs/mocks/call-counts) explains `Times` and `AnyTimes`.

## The rules [#the-rules]

| Part | Rule |
| --- | --- |
| Path | Equal to the mock path, or matched by it as a regular expression. Ignored when the mock has no URL. |
| Host | Equal to the mock host. Ignored when the mock URL has no host. |
| Scheme | Equal to the mock scheme. Ignored when the mock URL has no scheme. |
| Method | Equal to the mock method. |
| Headers, query parameters, form data | Each value is a regular expression matched against the received values. |
| Body | Equal to the mock body as a string, or equivalent JSON. `BodyRegexp` matches a regular expression. |
| Cookies, basic auth | Equal to the mock's values. |
| Custom matchers | Return `nil`. |

Every matcher must pass. A matcher whose part of the mock was not set, such as headers on a mock without `Header`, always passes.

## Paths are regular expressions [#paths-are-regular-expressions]

The mock path is a regular expression, and it is not anchored. `Get("http://users/api/user/\\d+")` matches `/api/user/1234`, and also `/api/user/1234/avatar`:

```go
// matches /api/user/1234 and /api/user/1234/avatar: the expression is not anchored
anyUserPath := apitest.NewMock().
	Get(`http://users/api/user/\d+`).
	RespondWith().
	Status(http.StatusOK).
	End()

// $ anchors the end, so /api/user/1234/avatar no longer matches
userOnly := apitest.NewMock().
	Get(`http://users/api/user/\d+$`).
	RespondWith().
	Status(http.StatusOK).
	End()

// leave out the scheme and host to anchor the start with ^ as well
anchored := apitest.NewMock().
	Get(`^/api/user/\d+$`).
	RespondWith().
	Status(http.StatusOK).
	End()
```

Regular expression characters in a path, such as `.`, `+` and `?`, also need escaping when you want them matched literally.

## Debugging a mismatch [#debugging-a-mismatch]

When no mock matches, the client receives an error, and the handler usually responds with an error status. Enable [`Debug`](/docs/guides/debugging) to see why each mock was rejected. In this run the users mock has a typo in its path, and the preferences mock expects a different token:

```text title="Debug output"
----------> inbound http request
GET /user/1234 HTTP/1.1
Host: sut


failed to match mocks. Errors: received request did not match any mocks

Mock 1 mismatches:
• received path /api/user/1234 did not match mock path /api/user/12345

Mock 2 mismatches:
• received path /api/user/1234 did not match mock path /api/preferences/1234
• received host users did not match mock host preferences
• not all of received headers map[Authorization:[Bearer s3cr3t]] matched expected mock headers map[Authorization:[Bearer token]]

----------> request to mock
GET /api/user/1234 HTTP/1.1
Host: users
User-Agent: Go-http-client/1.1
Authorization: Bearer s3cr3t
Accept-Encoding: gzip

<---------- response from mock

<---------- final response
HTTP/1.1 502 Bad Gateway
Content-Type: application/json

{"error":"upstream error"}
```

Mocks that have already answered their calls are skipped, so they do not appear in the list.

### In a sequence diagram [#in-a-sequence-diagram]

A [sequence diagram](/docs/reports/sequence-diagrams) shows the same failure at a glance. A call that matched no mock gets no response, so the report marks its arrow with a ✕ and labels the message **no response**:

```go
// the mock is for user 9999, so the call for user 1234 matches no mock
wrongUser := apitest.NewMock().
	Get("http://users/api/user/9999").
	RespondWith().
	Status(http.StatusOK).
	Body(`{"id": "9999", "name": "ola"}`).
	End()

apitest.New("reports a call that matched no mock").
	Report(apitest.SequenceDiagram()).
	Mocks(wrongUser).
	Handler(newUserAPI()).
	Get("/user/1234").
	Expect(t).
	Status(http.StatusBadGateway).
	End()
```

<ReportImage name="unmatched-mock" demo="/demo/unmatched-mock.html" alt="An apitest report where the call from sut to users is marked as having no response, and the test responds 502 Bad Gateway" />

[`ObserveMocks`](/docs/mocks/observing) reports every mocked call programmatically, including the ones that did not match.
