skip to content

How would you set and enforce a policy on WireMock catch-all mappings and --no-request-journal across teams?

level: principalimportance: should knowfreq 31%

answer

  1. policy on artefacts, not on culture
  2. every mapping names method and path
  3. journal on wherever fixtures are shared
  4. exceptions get an owner and a date

basics

~20 s

Make both failure modes reviewable rather than cultural. Require every mapping in a shared WireMock set to name a method and a URL constraint, and keep the request journal on in CI. A mapping answering anything becomes a time-boxed, owned exception.

solid answer

~50 s

Write the policy against artefacts a reviewer can see. First, every mapping in a shared WireMock set names a method and a URL constraint, so a diff shows what it can answer; a mapping that constrains neither is an exception carrying an owner and a removal date in its `metadata`. Second, the request journal stays on wherever fixtures are shared — `--no-request-journal` silently removes `verify(...)` from every suite on that instance, so it needs a named justification rather than a copied command line. Third, enforce both mechanically instead of in review: a CI step can ask the running instance for a request count and fail when WireMock reports the journal disabled, and the mapping set can be checked before it is loaded. Finally, measure the pressure that produces catch-alls, which is usually a fixture set nobody owns.

code

json · 23 lines
json
{
  "mappings": [
    {
      "name": "ferry-departures-dov-cal",
      "metadata": {
        "owner": "ferry-platform",
        "review": "2027-01-15"
      },
      "request": {
        "method": "GET",
        "urlPath": "/v1/routes/DOV-CAL/departures",
        "queryParameters": {
          "date": { "matches": "[0-9]{4}-[0-9]{2}-[0-9]{2}" }
        }
      },
      "response": {
        "status": 200,
        "headers": { "Content-Type": "application/json" },
        "bodyFileName": "ferry/departures-dov-cal.json"
      }
    }
  ]
}

go deeper

for a junior

Know what the policy protects against: a WireMock mapping broad enough to answer anything, and an instance started with the journal off, both of which make a passing suite meaningless.

for a middle

Be able to explain the mechanics behind each rule — what the journal switch removes, and what a blanket mapping absorbs — because a rule nobody can justify gets waived at the first red build.

for a senior

Describe the enforcement you would actually build: a CI probe that fails when the instance reports the journal disabled, a check over the mapping set before it loads, and a migration plan for the fixtures already in place.

for a principal

Own the trade-off: strictness costs teams time when a legitimate new endpoint has no stub yet, so decide where the exception path runs, who approves it, what evidence retires it, and when the rule is revisited.

## Why a convention will not hold Both failure modes appear under deadline pressure, and both relieve it immediately. A mapping that answers everything turns a red build green in one line; `--no-request-journal` makes a memory complaint go away in one flag. A rule that lives only in a style guide is waived at exactly the moment it matters, because the person adding it is unblocking a release at the end of a day. A policy that survives has to be attached to something a reviewer or a job can see. The policy has two rules and one enforcement mechanism each. ## Rule one: every shared mapping says what it can answer In a fixture set that more than one team loads, a mapping must constrain the request enough that a reader of the diff can tell which calls it will serve: - It names a **method**. - It names a **URL constraint** — a path, a path pattern, or a template. - It carries **`metadata`** naming an owner, so a mapping is attributable a year later. - A mapping that constrains neither method nor URL is not a mapping in this set; it is an **exception**, and an exception carries an owner and a removal date. The rule is deliberately about shape rather than intent, because shape is reviewable and intent is not. "Do not add catch-alls" is unenforceable; "a mapping in the shared set names a method and a URL constraint" is a checklist item that a reviewer applies in seconds and a script can apply for free. ## Rule two: the journal stays on wherever fixtures are shared `--no-request-journal` is a memory decision with a testing consequence, and the consequence is not local. The disabled journal raises `RequestJournalDisabledException` from the count, the matching-request lookup, the serve-event list and the journal removals, so **every** suite pointed at that instance loses `verify(...)` at once — including suites whose owners never saw the command line. On a shared instance that makes the flag an architectural decision, not a runtime tweak, and it should require a named justification and an owner in the same way an exception mapping does. ## The same two shapes in the other products | Product | The "answers everything" shape | The "stops recording" switch | |---|---|---| | WireMock | a mapping constraining neither method nor URL, such as `any(anyUrl())` | `--no-request-journal`, after which the disabled journal raises `RequestJournalDisabledException` | | MockServer | an expectation whose request matcher constrains nothing | `mockserver.disableLogging`, which disables the log and the processing of log events | | Mountebank | a stub with an empty `predicates` array | `recordRequests` on the imposter, which decides whether requests are retained | Keep the table in the policy document itself: a team migrating between products otherwise re-acquires both problems under different names. ## Enforcing it where it cannot be argued with 1. **Probe the instance in CI.** In WireMock, `POST /__admin/requests/count` with a request pattern returns a count while the journal is live and reports the journal as disabled when it is not. Run it before the suite and fail the job on the disabled answer — that is the whole check, and it catches a flag copied from someone else's Compose file. 2. **Check the mapping set before it is loaded.** The mappings are data. A job can read the set the shared fixture publishes and fail when an entry constrains neither method nor URL, which moves the rule out of review and into the pipeline. 3. **Make the exception carry its own expiry.** An exception mapping with `metadata` naming an owner and a review date can be listed on a schedule, so the set is audited without anyone remembering to audit it. 4. **Audit periodically, not once.** New mappings arrive weekly; a rule applied only to new entries leaves the original set untouched, and the original set is where the oldest catch-all lives. ## The exception path, and why it must exist A policy with no exception path is routed around. Teams do need to unblock work: a new ferry endpoint appears in the client before anyone writes its mapping, and waiting for a fixture review to unblock a release is not a trade most teams will make. So give the exception a shape — scoped to a path prefix rather than everything, held in that team's own fixture set rather than the shared one, carrying an owner and a date — and make the sanctioned route faster than the workaround. The goal is not that a broad mapping is impossible; it is that it is visible, attributable and temporary. ## Measure the pressure, not the rules Judge the policy by what it produces rather than by its own completeness: - Count exceptions and how long they live. Rare, owned, short-lived exceptions mean the policy is holding. - Watch where they cluster. Exceptions concentrated around one service usually indicate a fixture set with no owner and no easy path to add a mapping, which is a staffing problem wearing a testing costume. - Track how often the journal probe fires. Repeat offences point at a shared command line, not at a careless person. Revisit the whole thing when the fixture set changes hands, because the reason the original catch-all was added is nearly always institutional memory that has since left the team.

  • What do you do about a team that genuinely needs a broad mapping today?
    Give them an exception path rather than forcing a workaround. Scope the mapping to a path prefix instead of everything, attach `metadata` naming an owner and a review date, and keep it in that team's own fixture set rather than the shared one. The point of the policy is that a broad mapping is visible, attributable and temporary — not that it is impossible, because an impossible rule is simply routed around.
  • How do you tell whether the policy is actually working?
    Count exceptions and how long they live, not how many rules you wrote. If broad mappings are rare, owned and short-lived, and no shared instance runs with the journal off, the policy is holding. If exceptions cluster around one service, the real problem is usually a fixture set with no owner and no cheap route to add a mapping, and tightening the rule further will make that worse rather than better.

saying these in an interview costs you the question

  • Bans catch-alls in a style guide with nothing checking it
  • Lets each team decide, then shares the fixture set anyway
  • Treats --no-request-journal as a harmless performance setting
  • Writes review rules but never measures why catch-alls appear
  • Applies the rule to new mappings and never revisits the old set