# echolot mock (/docs/cli/mock)

`echolot mock` serves a mock: a mock saved in a workspace, with its [routes made by hand](/docs/mocks/routes) and its
spec if it has one, or an OpenAPI document, whose operations answer with their documented examples or a body made from
their schema. Use it to build a client before the API exists, or to give a CI job a server that answers the way you
want. It serves the same mocks as the [Mocks page](/docs/mocks).

```sh
echolot mock <source> [--workspace <workspace>] [--port <port>] [--share] [--delay <ms>] [--failure-rate <percent>] [--no-validate] [--routes <file>]
```

`<source>` is a spec file (YAML or JSON), or with `--workspace` the name of a mock saved in that workspace.

## Mock a spec [#mock-a-spec]

```sh
echolot mock Alpenglow.echolot/specs/alpenglow.yaml --port 4010
```

```text
Mock of Alpenglow demo shop: 9 operations at http://127.0.0.1:4010/v1 (Ctrl-C stops it)
```

The mock answers at the path of the spec's first server (here `/v1`). Each request it answers is a line on standard
output: the status, the method and path, the operation it matched, where the answer came from, and the time.
Problems with the request are listed below it.

```text
200 GET /v1/products/TNT-MH-2P  → GET /products/{sku} (generated)  0 ms
400 POST /v1/orders  → POST /orders  0 ms
    body $.lines: expected array, got string
```

**Requests are checked against the spec.** A request whose parameters or body break the spec gets a `400` that says
what is wrong:

```json
{
  "error" : "The request does not match the spec (POST /orders).",
  "problems" : [
    "body $.lines: expected array, got string"
  ]
}
```

`--no-validate` answers such requests anyway.

**Choosing an answer.** By default an operation answers with its first success response and its first example. A
request can ask for another one with `Prefer: code=404, example=empty`, or with Postman's `x-mock-response-code` and
`x-mock-response-name` headers.

## Mock a workspace's mock [#mock-a-workspaces-mock]

With `--workspace`, `<source>` names a mock saved on the Mocks page (its file name in `mocks/` without `.toml`, or its
name). Its port, delay, failure rate, request checks, chosen responses and routes apply, and the options you give
override them. Its routes in JavaScript (`mocks/<name>.js`) answer first, then its routes made by hand, then its spec;
see [scripted routes](/docs/mocks/scripted-routes) and [routes and fake data](/docs/mocks/routes).

```sh
echolot mock shop -w Alpenglow.echolot --delay 300
```

A mock of routes needs no spec:

```sh
echolot mock storefront -w Shop.echolot
```

```text
Mock of Storefront: 3 routes at http://127.0.0.1:4321 (Ctrl-C stops it)
200 GET /users/42  → GET /users/{id} (OK)  1 ms
404 GET /users/0  → GET /users/{id} (Not found)  0 ms
```

Each line names the route that answered and, in parentheses, the response it gave. Fake values in the bodies are made
again for every request. To make fake data without a server, see [echolot fake](/docs/cli/fake).

## Options [#options]

| Option | Meaning |
| --- | --- |
| `-w`, `--workspace <folder>` | The workspace folder holding the mock. |
| `--port <port>` | The port. Default: the mock's own, or 4010. |
| `--share` | Answer on every network interface, not only this Mac: for containers and phones. |
| `--delay <ms>` | Milliseconds before each answer. |
| `--failure-rate <percent>` | Percent of requests answered with an injected `500`. |
| `--no-validate` | Answer requests that break the spec instead of refusing them with `400`. |
| `--routes <file>` | Routes in JavaScript that answer before the spec. Default: the workspace mock's `mocks/<name>.js`. |

Without `--share` the mock listens on 127.0.0.1 only, so nothing else on the network can reach it. With `--share`,
anyone who can reach your Mac can.

A request body over the mock's limit gets a `413` and never reaches a route.

## In CI [#in-ci]

Start the mock in the background and run against it. Alpenglow's **Local** environment points `{{baseURL}}` at
`http://localhost:8787/v1`, so a mock on port 8787 answers its requests:

```sh
echolot mock Alpenglow.echolot/specs/alpenglow.yaml --port 8787 &
echolot run Alpenglow.echolot --env local --folder catalog
kill %1
```

## Exit codes [#exit-codes]

The mock runs until you stop it. It exits with `64` for a wrong option or a mock name the workspace doesn't have,
and with `1` when the spec can't be read or the port is taken.
