skip to content

Mapping Sprawl

A mapping catalogue that outgrew its owners: the endpoint listing stubs never served, definition and body files piling up on disk, start-up initializers, and overlaps nobody can reconstruct.

on this pageshow

explore

questions

4

In WireMock, which stubs does GET /__admin/mappings/unmatched list, and which problems does it miss?

level: middleimportance: must knowfreq 55%

answer

  1. an inventory question, not a correctness one
  2. zero requests served since start-up
  3. scoped to one instance's lifetime
  4. stubs, not requests, despite the name
  5. findUnmatchedStubs is not a static

basics

~20 s

In WireMock, GET /__admin/mappings/unmatched lists the stub mappings the running instance never served. It is a census of dead weight, not of correctness. It says nothing about a stub served with a stale body, nor about requests that matched nothing.

solid answer

~50 s

In WireMock, `GET /__admin/mappings/unmatched` returns the stub mappings that the running instance has never served a request from, and `DELETE` on the same path removes exactly that set. The Java equivalent is `findUnmatchedStubs()`, which in WireMock 4 is declared on `WireMockServer`, `Admin`, `DslWrapper` and `HttpAdminClient` — **not** on the static `WireMock` facade, whatever the documentation shows. Read the result as dead weight scoped to one instance's lifetime: a museum ticketing stub for `GET /tickets/{ref}` that this shard happened not to exercise looks exactly like one nobody has needed for a year. Two failures people expect from it are out of reach — a stub that was served but answers with a stale body, and a request that matched no stub at all, which is a question about the request journal rather than about the catalogue.

code

java · 10 lines
java
import com.github.tomakehurst.wiremock.WireMockServer;
import com.github.tomakehurst.wiremock.stubbing.StubMapping;
import java.util.List;

// museumApi is the WireMockServer the museum ticketing suite has just run against.
// findUnmatchedStubs() is declared on WireMockServer and Admin,
// not on the static WireMock facade, whatever the docs show.
List<StubMapping> neverServed = museumApi.findUnmatchedStubs();

System.out.println("stubs never served: " + neverServed.size());

go deeper

for a junior

Recall that this WireMock endpoint lists stubs the server loaded but never used, and that it is about stub mappings rather than incoming requests. The two names are easy to swap under pressure.

for a middle

Explain the mechanics: the count is cumulative per instance, DELETE on the same path removes that set, and findUnmatchedStubs() lives on WireMockServer and Admin, not on the static facade.

for a senior

Show where the census misleads — sharded runs, tag filters, nightly-only error paths — and say plainly that a served-but-stale stub is invisible to it. Then describe how you would still make it useful in CI.

for a principal

Frame it as the one number that turns catalogue sprawl from an opinion into a tracked metric, and be clear about what that metric cannot buy you, so nobody mistakes a shrinking catalogue for a correct one.

## The one thing the endpoint counts A WireMock instance records, for every stub mapping it has loaded, whether that mapping has ever been selected to answer a request. WireMock's `GET /__admin/mappings/unmatched` returns the mappings for which the answer is still no: stubs that were loaded, sat there, and served nothing. `DELETE` on the same path removes exactly that set from the running instance. A mapping is in the list if and only if it has served zero requests since this instance started — nothing else is being measured. That single fact is what makes the endpoint valuable and what makes it easy to over-read. It is the measurable face of a catalogue nobody maintains: a museum ticketing instance that loads four hundred stubs and reports three hundred and ten never-served has a problem you can put a number on, argue about in a review, and watch move build over build. What it is **not** is evidence about whether any individual stub is still *right*. ## The Java surface, and the trap in it From an embedded test the same census is WireMock's `findUnmatchedStubs()`. In WireMock 4 that method is declared on `WireMockServer`, on the `Admin` interface, on `DslWrapper` and on `HttpAdminClient` — and not on the static `WireMock` facade, even though documentation pages present it as though it were. Writing `WireMock.findUnmatchedStubs()` will not compile; you need a handle on the server or on an admin client. The neighbouring names are a separate source of confusion worth keeping straight: - `findUnmatchedStubs()` in WireMock — stubs that served nothing. On `WireMockServer` / `Admin` / `DslWrapper` / `HttpAdminClient`. - `findUnmatchedRequests()` in WireMock — the static form, and it asks about requests, not stubs. - `findAllUnmatchedRequests()` in WireMock — the instance form of that same request-side query. The names are one word apart and answer opposite questions. *Unmatched stubs* means this stub matched nothing; *unmatched requests* means this request matched no stub. ## What "never served" does not mean The endpoint reports over one instance's lifetime and over whatever traffic that instance happened to receive. Both halves matter. | the worry | does WireMock's `GET /__admin/mappings/unmatched` show it? | |---|---| | a stub no test has needed for a year | yes, provided the whole suite ran against this instance | | a stub only one nightly shard exercises | no — to every other run it looks identical to a dead one | | a stub that answered but with a stale body | no — being served is all the endpoint counts | | a request that matched no stub at all | no — that is a question about the request journal | | a stub shadowed by a broader overlapping mapping | it appears, but as an overlap to resolve, not a stub to delete | ## The two failures people expect from it Teams reach for this endpoint hoping it will catch a stale catalogue, and it cannot. A museum ticketing stub for `GET /tickets/{ref}` that returns a body missing the `admittedAt` field the real API now sends is served on every run, so it never appears here — being wrong and being unused are different properties, and only one of them is counted. Equally, a client call to `/exhibitions/SUMMER-26/availability` that no mapping matches is a request-side event. The mapping census has nothing to say about it, because no mapping was involved at all. Read the endpoint for what it is: an inventory question. *How much of what we are loading is doing any work?* ## Using it inside a museum ticketing suite - Take the census **after** the suite finishes, not between tests; the count is cumulative for the instance. - Take it from a **full, unfiltered** run. A sharded or tag-filtered run produces a census about that slice only. - Compare it against the total from WireMock's `GET /__admin/mappings` — the ratio is the number worth tracking, not the raw count. - Circulate the never-served list before deleting anything, because the endpoint cannot distinguish *obsolete* from *only exercised elsewhere*. - Keep it out of per-test assertions; a stub going unserved in one test is entirely normal and says nothing. - Store the list as a build artefact, so two consecutive full runs can agree before anything is removed. Used that way the endpoint turns a vague complaint — *the mapping set is out of control* — into a repeatable measurement a team can act on without guessing. Used carelessly, it becomes the justification for deleting the one stub that only the nightly job needed.

  • Your CI shard reports forty never-served WireMock stubs, but the full suite reports none. What changed?
    Only the traffic. `GET /__admin/mappings/unmatched` reports on what this instance was actually asked for, so a shard that exercises a sixth of the museum ticketing endpoints leaves the rest unserved. The catalogue is identical in both runs; the census is a property of the run, and only the full, unfiltered one describes the catalogue.
  • In WireMock, what does DELETE /__admin/mappings/unmatched actually remove?
    The never-served stub mappings from the running instance, and nothing else. The JSON definitions under `mappings/` and every body under `__files/` are untouched, so restarting from the same directory reloads the full set. Making a prune durable means removing the definition files in the repository, or persisting the instance's current set back with `POST /__admin/mappings/save`.
  • Can the WireMock never-served census tell you a stub has drifted from the real museum ticketing API?
    No. A drifted stub is served on every run, so it never appears in the list. The endpoint counts whether a mapping was selected, not what it returned. Detecting that a canned response no longer resembles the real service is a different exercise entirely, and needs the real service's shape as evidence rather than the instance's own bookkeeping.

saying these in an interview costs you the question

  • Confusing unmatched stubs with unmatched requests
  • Calling findUnmatchedStubs on the static WireMock facade
  • Expecting the census to reveal a stale response body
  • Reading a shard's census as a statement about the catalogue
  • Assuming a never-served stub is automatically obsolete
open as a page

In WireMock, what do the mappings/ and __files/ directories hold for a museum ticketing stub set?

level: juniorimportance: should knowfreq 66%

basics

~20 s

In WireMock, mappings/ holds the JSON stub definitions, each a request matcher plus a canned response. WireMock's __files/ holds the response bodies those definitions name with bodyFileName. Both directories only ever grow: nothing in the server retires a file.

open as a page

How would you govern a sprawling WireMock mappings/ directory for a museum ticketing API across many teams?

level: principalimportance: should knowfreq 48%

basics

~20 s

Measure the catalogue before you police it: WireMock's GET /__admin/mappings/unmatched names every stub a run never served. Record an owner in each WireMock mapping's metadata, and prune only on that evidence, never on a hunch about which stubs look stale.

open as a page

When is it safe to act on WireMock's DELETE /__admin/mappings/unmatched for a museum ticketing catalogue?

level: seniorimportance: nice to knowfreq 40%

basics

~20 s

In WireMock, DELETE /__admin/mappings/unmatched removes the stubs an instance never served, so it is only safe after a run that exercised the whole catalogue. A sharded, tagged or aborted run makes live stubs look dead. The delete is in-memory only.

open as a page