Workers IO workers.io
skills docs blog login

Mocks

How to model external services your workload depends on.


Mocks describe how external services respond during a run. Use them when your workload depends on APIs, webhooks, providers, or services you do not want to call directly.

Good mocks let you ship faster because your workload can exercise user-critical behavior without waiting on real third-party accounts, fragile test environments, or one-off fixtures.

When to use a mock

Use a mock for service behavior:

  • A payment provider accepts a charge.
  • An email API returns a message ID.
  • A storage API returns an object.
  • An identity provider returns a user profile.
  • A webhook endpoint sends a retryable error.
  • A downstream service returns an unusual but valid payload.

Do not use mocks to describe network conditions like delay, packet loss, or blocked paths. Those belong in fault models.

Common services to model

External mocks use JSON configuration files. Model the HTTP services your workload needs, such as:

  • AWS services.
  • GitHub.
  • Stripe.

For your own service, start with the smallest simulation that captures the request and response behavior the workload depends on.

File location

Put the project-level mock file here:

.workers/external-mocks.json

When a project run starts, Workers IO uses this file automatically. You do not need to pass a mock flag to wio simulate create.

Validate the mock profile before committing or running it:

wio validate mocks

Example

This mock makes a payment charge request succeed:

{
  "data": {
    "pairs": [
      {
        "request": {
          "method": [{ "matcher": "exact", "value": "POST" }],
          "destination": [
            { "matcher": "exact", "value": "payments.example.com" }
          ],
          "path": [{ "matcher": "exact", "value": "/charge" }]
        },
        "response": {
          "status": 200,
          "body": "{\"id\":\"pay_123\",\"status\":\"succeeded\"}",
          "encodedBody": false,
          "headers": {
            "Content-Type": ["application/json"]
          }
        }
      }
    ]
  },
  "meta": {
    "schemaVersion": "v5.2"
  }
}

The request section says which call this mock handles. The response section says what the workload receives.

Good mocks

Good mocks are specific enough to catch wrong calls.

Good:

POST payments.example.com/charge returns 200 with a successful charge ID.

Bad:

Any request to payments.example.com returns 200.

The good mock proves the workload made the expected request. The bad mock can hide bugs because almost any call appears to work.

Good:

The first webhook attempt returns 503. The retry returns 200.

Bad:

The webhook always returns 200.

The good mock exercises retry behavior. The bad mock only proves the happy path.

What to model

Start with the smallest set of responses your workload needs:

  • One normal success response.
  • One retryable failure.
  • One permanent failure.
  • One edge-case payload users may trigger.

Add more cases only when they explain a real behavior your users depend on.

Running with mocks

After committing .workers/external-mocks.json, run the workload normally:

wio simulate create <project-id> \
  --command "python3 .workers/workloads/checkout.py" \
  --workload-path ".workers/workloads/checkout.py" \
  --depth 1

Keep mocks honest

Mocks are useful when they behave like the real service from your workload’s point of view. Keep request matching narrow, response bodies realistic, and failure cases explicit.

If a mock starts encoding too much application logic, move that logic into the workload checks instead.