Creating Mocks

File Mocks

File mocks live in .hcl files inside your project, so they can be reviewed, versioned, and run identically by every developer and in CI. By the end of this page you will know the full anatomy of a mock file: routes, path parameters, response fields, and how to organize mocks across files.

Your first mock file

Create a folder for your mocks and add a file to it. The file name is up to you, only the .hcl extension matters.

mocks/
  users.hcl
mock "GET /users/{id}" {
format = "json"
body = <<-EOF
{
"id": {{request.params.id}},
"name": "Alice Martins",
"email": "alice@example.com"
}
EOF
}

Point the CLI at the folder. The --watch flag reloads mocks whenever a file changes, which is what you want during development.

$mocko --watch mocks
$curl http://localhost:8080/users/7
{ "id": 7, "name": "Alice Martins", "email": "alice@example.com" }

The {id} segment in the route matched the request path, and {{request.params.id}} rendered it into the response. Mock bodies are templates, and they can do much more than echo parameters. The next pages cover that in depth; this page focuses on the file itself.

The mock block

Every mock starts with a route string: mock "METHOD /path". The method can be GET, POST, PUT, DELETE, PATCH, or * to match any method. Path segments wrapped in braces, like {id}, are parameters: they match any value in that position and expose it to the body template.

Inside the block, everything is optional. A mock with an empty body and no fields is already a valid 200 response. These are the fields you will use most:

mock "POST /users" {
status = 201
delay = 300
format = "json"
body = <<-EOF
{
"id": 42,
"name": "{{request.body.name}}"
}
EOF
}
  • status sets the response code. If you omit it, Mocko uses 201 for POST and 200 for everything else, so the status = 201 above is redundant and shown only for clarity.
  • delay waits the given number of milliseconds before responding. Useful for testing loading states and timeouts.
  • format sets the response Content-Type from a short name: json, html, text, xml, javascript, or css.
  • body is the response body, rendered as a template on every request.

Response headers

When you need headers beyond Content-Type, add a headers block:

mock "GET /users/{id}" {
headers {
Content-Type = "application/json"
Cache-Control = "no-store"
X-Request-Trace = "mocked"
}
body = <<-EOF
{ "id": {{request.params.id}} }
EOF
}
format and an explicit Content-Type header are mutually exclusive: setting both fails validation when the file loads. Use format alone, or declare Content-Type inside headers along with the rest.

Multi-line bodies

Bodies almost always span multiple lines, so mock files use HCL heredocs. The <<-EOF form (with the dash) strips the leading indentation from every line, which lets you indent the body naturally inside the block. The <<EOF form preserves whitespace exactly as written.

# Strips leading indentation (use this one)
body = <<-EOF
{ "name": "Alice" }
EOF

# Preserves indentation exactly
body = <<EOF
{ "name": "Alice" }
EOF
When the body is valid JSON, Mocko pretty-prints it automatically, so you never need to worry about whitespace or indentation inside JSON bodies.

Naming and organizing mocks

Three more fields help once a project accumulates mocks. None of them change how a mock responds:

  • name is the label shown in the Mocko UI. It defaults to the file path.
  • labels is a list of tags used for filtering in the UI, for example labels = ["users", "errors"].
  • enabled = false turns a mock off without deleting it. Handy for keeping an error-case mock in the file and flipping it on when needed.

Splitting mocks across files

Mocko loads every .hcl file under the folder you pass to the CLI and merges them. Nested folders are purely organizational, so structure them however reads best for your project:

mocks/
  users.hcl          # mocks for /users routes
  orders.hcl         # mocks for /orders routes
  shared/
    data.hcl         # data blocks shared across all mocks

Mocks, hosts, and data blocks from all files end up in one merged configuration. Files and folders whose names start with a dot are ignored.

When something goes wrong

If a file has a syntax error or an invalid field, Mocko prints the error to the terminal when it loads the folder, including the line and column for template errors. With --watch you can fix the file and save; Mocko reloads and reports again.

Behavior details

  • File mocks appear in the Mocko UI as read-only, so the versioned files stay the single source of truth.
  • There is also a host field for scoping a mock to a virtual host, covered in Proxying and Hosts, and a parse = false option for streaming raw request bodies, covered in the mock file reference.

Next

Mocko also has a control panel for creating mocks without touching files. Continue to UI Mocks to see when each workflow fits.