skip to content

Fidelity Risks

The server features that expose a stand-in gone stale: the request journal, near-miss reports, catch-all mappings, refreshing from upstream. A suite that stays green over a stale mock proves nothing.

on this pageshow

explore

questions

25

In MockServer, how do you verify that a POST to /catalogue/v1/holds actually arrived?

level: juniorimportance: must knowfreq 68%

answer

  1. the server is the only witness
  2. every received request is journalled
  3. a pattern, not a full description
  4. MockServerClient.verify plus a request definition
  5. VerificationTimes.once pins it to one

basics

~20 s

MockServer keeps a journal of every request it receives, and MockServerClient.verify asserts against it. Pass a request definition describing the POST plus a VerificationTimes count. When nothing matches, verify throws an AssertionError listing the requests the journal did record.

solid answer

~40 s

MockServer's request journal records every request the server received, and `MockServerClient.verify` is how a test interrogates it. Build a request definition with the static `request()` factory — `request().withMethod("POST").withPath("/catalogue/v1/holds")` — and hand it to `verify`, optionally with a `VerificationTimes` count such as `VerificationTimes.once()`. Omit the count and the assertion means only "at least one matching request arrived". MockServer matches that definition against the journal with the same rules it uses to pick an expectation, so a definition naming only a method and path is satisfied by any body and any headers. If nothing matches, `verify` throws an `AssertionError` whose message carries the requests the journal actually held, which usually shows the client hit `/catalogue/v1/hold` or sent a `GET`. WireMock's count matchers are `exactly(`, `lessThan(`, `lessThanOrExactly(`, `moreThan(` and `moreThanOrExactly(`, and it has no `never()`.

code

java · 10 lines
java
import static org.mockserver.model.HttpRequest.request;
import org.mockserver.verify.VerificationTimes;

// the service under test has just placed a hold on a catalogue title
mockServerClient.verify(
    request()
        .withMethod("POST")
        .withPath("/catalogue/v1/holds"),
    VerificationTimes.once()
);

go deeper

for a junior

Be ready to write the call from memory: MockServerClient.verify with a request definition built by request(), with the method and path set. Say plainly that failure throws rather than returning false.

for a middle

Explain that the definition is a pattern matched against the journal, so unnamed headers and bodies are unconstrained, and that omitting VerificationTimes means at least once rather than exactly once.

for a senior

Show where the verification sits in a test that also asserts on your own code's outcome, and how you read the AssertionError message to separate a client bug from a badly written request definition.

for a principal

Set the standard for how much of a request a verification may pin — path and method only, or body too — and decide who maintains those definitions when the catalogue contract shifts.

## Why the server has to be the witness A test that puts a stub server in front of a dependency can prove two different things. The first is that the code under test coped with the canned reply — the branch it took, the value it returned, the error it surfaced. Assertions on your own code cover that. The second is that the code **sent the right request at all**: that "place a hold on this title" really produced a `POST /catalogue/v1/holds`, rather than short-circuiting on a cached value or swallowing an exception in a `catch` block nobody noticed. No assertion inside your own process can see that, because the only component that saw the bytes on the wire is the stub server. MockServer answers it from its **request journal** — the record it keeps of every request the server received while the test ran, held independently of which expectation, if any, produced the reply. Verifying is nothing more than asking that journal a question and failing the test when the answer is wrong. ## The anatomy of a MockServer verification `MockServerClient.verify` takes a request definition and, optionally, a count. - `request()` is the static factory on MockServer's `HttpRequest` that starts the definition. - `withMethod("POST")` and `withPath("/catalogue/v1/holds")` narrow it to the call you care about. - A `VerificationTimes` argument pins how many matching requests the journal must hold. MockServer's set is `never()`, `once()`, `exactly(int)`, `atLeast(int)`, `atMost(int)` and `between(int, int)`. - Omit the count and the assertion means only "at least one matching request arrived". - On success the call returns normally; on failure it throws an `AssertionError`. ```java mockServerClient.verify( request().withMethod("POST").withPath("/catalogue/v1/holds"), VerificationTimes.once()); ``` ## What the definition asserts, and what it silently ignores The definition is a **pattern**, not a description of the whole request. MockServer matches it against the journal with the same rules it uses to select an expectation, so every aspect the pattern does not mention is left unconstrained. That is the single most common reason a verification passes while the integration is broken. | verification call | passes when the journal holds | says nothing about | |---|---|---| | `verify(request().withPath("/catalogue/v1/holds"))` | one or more requests on that path | the method, the body, the headers | | `verify(request().withMethod("POST").withPath("/catalogue/v1/holds"), VerificationTimes.once())` | exactly one POST on that path | the body and the headers | | `verify(request().withPath("/catalogue/v1/holds"), VerificationTimes.never())` | no request at all on that path | every other path | ## Reading the failure When the assertion fails, MockServer's `AssertionError` carries both the definition you asked for and the requests the journal actually held. In practice that message does most of the diagnosis: 1. The recorded entry shows `/catalogue/v1/hold` where you asked for `/catalogue/v1/holds` — a typo or an unencoded segment in the client. 2. The recorded entry is a `GET` where you asked for a `POST` — the code fell into a read path and never attempted the write. 3. The journal holds two matching requests where you asked for `once()` — a retry, or a duplicated call the feature never intended. 4. The journal is empty — the client never reached this server, which usually means it was pointed at the wrong port or base URL. ## Where the assertion belongs in the test A verification is a second assertion, not a replacement for the first. The usual shape of a catalogue test is: - Arrange an expectation so `POST /catalogue/v1/holds` answers with `201` and a body carrying `holdId` and `queuePosition`. - Act by calling your own service method. - Assert on what your code returned or stored — the hold id it surfaced to its caller. - Verify against the journal that the outbound request was actually made, once. Drop the last step and a client that never called the catalogue can still pass. Drop the third and you have proved traffic went out and nothing at all about whether the feature worked. ## Common mistakes - Treating a green `verify` as proof the body was right. It proves only that a request matching the pattern you wrote arrived; a pattern naming just a path is satisfied by an empty POST. - Assuming a count is implied. Without a `VerificationTimes` argument the assertion is "at least once", so a client that fires the hold three times still passes. - Confusing the two sides of the API. `withStatusCode` belongs to MockServer's `response()` on the expectation; verification is about the request and takes no status at all. - Verifying before the work has finished. If the catalogue call runs on another thread, the journal may not hold the request yet when the assertion executes. - Reading a passing verification as proof that an expectation matched. The journal records what arrived, not what answered it.

  • What does a MockServer verification with no VerificationTimes argument assert?
    It asserts that at least one request matching the definition reached the server. The journal may hold five identical hold requests and the assertion still passes. Pass `VerificationTimes.once()` — or `exactly(1)` — when the count is part of what you are proving, which for a non-idempotent call such as placing a hold it usually is.
  • Your verify fails but the client definitely called the catalogue. Where do you look first?
    The `AssertionError` message lists the requests the journal did hold, so compare them field by field against the definition you wrote. Most failures are a path that differs by a segment or a trailing slash, a method mismatch, or an assertion that ran before an asynchronous call had completed.
  • Does a passing MockServer verification prove that an expectation matched the request?
    No. The journal records requests the server received, not which expectation answered them, so a request that matched nothing at all still satisfies `verify`. Pair the verification with an assertion on what your own code did with the reply, or the test can be green while the client never received the response you staged.

saying these in an interview costs you the question

  • Thinks a passing verify proves the request body was correct
  • Believes verify with no count argument asserts exactly one request
  • Expects verify to return a boolean instead of throwing on failure
  • Confuses the response builder's withStatusCode with a verification argument
  • Assumes the journal only records requests that an expectation matched
open as a page

In WireMock, what does the --no-request-journal flag switch off, and what then happens to verify()?

level: juniorimportance: must knowfreq 46%

basics

~20 s

WireMock's --no-request-journal flag stops the server recording the requests it receives. Because nothing is recorded, verification is not weakened but abolished: the disabled journal raises RequestJournalDisabledException. A verify() call after that flag can never pass, whatever the client sent.

open as a page

In WireMock, what does makeStubsPersistent(false) change about the stubs a re-recording produces?

level: juniorimportance: must knowfreq 58%

basics

~20 s

With makeStubsPersistent set to false, WireMock keeps the regenerated stubs in memory only: they serve requests while the instance lives and vanish on restart. Its default, true, writes each one as a JSON file under the mappings directory.

open as a page

In MockServer, what does each VerificationTimes factory assert about how often a request arrived?

level: middleimportance: must knowfreq 62%

basics

~20 s

VerificationTimes carries six factories: never, once, exactly, atLeast, atMost and between. Each turns a MockServer verification from at least one matching request into a precise count assertion, so a duplicated or missing hold request fails the test rather than passing.

open as a page

In MockServer, what does upsert(openAPIExpectation(...)) build from an OpenAPI document?

level: middleimportance: must knowfreq 66%

basics

~20 s

MockServer reads the OpenAPI document, then creates one expectation for each operation it selects, matching that operation's method, path and declared parameters. Each expectation replies with the response the document declares. The entry point is upsert(OpenAPIExpectation...) on MockServerClient.

open as a page

In WireMock, what does a NearMiss's MatchResult.getDistance() actually measure?

level: middleimportance: must knowfreq 66%

basics

~20 s

MatchResult.getDistance() scores how badly one request missed one WireMock stub mapping. It runs from 0, meaning every matcher passed, to 1, meaning nothing matched. WireMock ranks a near-miss list by that score, so the closest mapping is listed first.

open as a page

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

level: middleimportance: must knowfreq 55%

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.

open as a page

In MockServer, how does VerificationTimes.never differ from verifyZeroInteractions on a catalogue test?

level: seniorimportance: must knowfreq 52%

basics

~20 s

MockServer's VerificationTimes.never asserts that no request matching one definition arrived, so it says nothing about other traffic. verifyZeroInteractions asserts the journal is empty outright. A never assertion built on a mistyped path passes vacuously; the empty-journal check cannot.

open as a page

In WireMock, what does GET /__admin/requests/unmatched return during a failing test?

level: juniorimportance: should knowfreq 60%

basics

~20 s

WireMock's unmatched-requests endpoint returns every request the server received that no stub mapping served. Each one arrives as a full logged request: method, URL, headers and body. It is the first place to look when a stub-backed test unexpectedly gets a 404.

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

In WireMock, what does a catch-all stub that answers every request hide in a ferry-timetable suite?

level: middleimportance: should knowfreq 52%

basics

~20 s

A WireMock catch-all stub answers every request, even ones nobody stubbed. A wrong path or an unstubbed ferry endpoint gets the same canned 200, so the client's error branches never run. The specific mappings beneath it stop being served.

open as a page

When should a MockServer suite assert with verify counts rather than retrieved request bodies?

level: seniorimportance: should knowfreq 46%

basics

~20 s

Use MockServer verify counts for facts about traffic: the hold call happened once, the cancellation never did. Reach for retrieveRecordedRequests only where a field carries contract meaning, because every field you assert is one the catalogue can later change.

open as a page

In MockServer, why retrieve recorded catalogue hold requests instead of asserting the whole body in verify?

level: seniorimportance: should knowfreq 50%

basics

~20 s

MockServer's verify answers only match or no match, so a whole-body pattern breaks on any generated field. retrieveRecordedRequests hands the received requests back as objects, so your own assertions can target the fields that matter and report which one differed.

open as a page

In MockServer, how do you make one operation of a spec-derived beehive telemetry mock answer 503?

level: seniorimportance: should knowfreq 53%

basics

~20 s

MockServer's OpenAPIExpectation takes withOperationsAndResponses, a map from operation id to the response that operation should answer with. Mapping getHiveWeight to 503 makes only that operation fail. The map also selects the set: unlisted operations get no expectation at all.

open as a page

In MockServer, what does withSpecUrlOrPayload() accept, and what changes when you point it at a URL?

level: seniorimportance: should knowfreq 51%

basics

~20 s

MockServer's withSpecUrlOrPayload accepts a URL, a file or classpath location, or the OpenAPI document inline. A URL is resolved when upsert runs, so the expectation set becomes whatever that host served then. A pinned copy trades currency for reproducibility.

open as a page

A WireMock stub for a vineyard harvest-log endpoint never matches — how do you diagnose it?

level: seniorimportance: should knowfreq 55%

basics

~20 s

WireMock records every request that no stub mapping served. Its near-miss report ranks the closest mapping for each of those, scoring how far apart they are. Read the field the report names as differing, then fix the stub or the client.

open as a page

In WireMock, when does --print-all-network-traffic tell you what the near-miss report cannot?

level: seniorimportance: should knowfreq 46%

basics

~20 s

WireMock's near-miss report compares a request as WireMock already parsed it. Starting WireMock with --print-all-network-traffic dumps the raw bytes of every exchange instead. Reach for it when the mismatch is in framing, encoding or a header the parser normalised.

open as a page

Why does a regenerated WireMock mapping set diff noisily against the committed meter-API set?

level: seniorimportance: should knowfreq 47%

basics

~20 s

Most of the diff is churn, not change. WireMock gives every regenerated mapping a fresh id and a generated file name, and volatile response values differ per call. Normalise both sets, then compare request and response pairs.

open as a page

In WireMock, how do you regenerate a committed mapping set by re-pointing recordSpec().forTarget( at the live meter API?

level: seniorimportance: should knowfreq 64%

basics

~20 s

Point a fresh WireMock recording at the live district heating meter API with forTarget, replay the same traffic, and let the recorder write a new mapping set. Then diff that set against the committed one rather than overwriting it blindly.

open as a page

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

level: principalimportance: should knowfreq 31%

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.

open as a page

In MockServer, how would you choose between a document's declared examples and withGenerateFromSchema() across many teams' beehive telemetry mocks?

level: principalimportance: should knowfreq 45%

basics

~20 s

Prefer the document's declared examples: MockServer returns a body a person wrote and a reviewer saw. Use withGenerateFromSchema on MockServer's HttpResponse where only a schema exists. Treat generated values as structurally valid and semantically meaningless, and never assert on them.

open as a page

How would you govern one WireMock proxyAllTo( canary mapping against the live meter API across many suites?

level: principalimportance: should knowfreq 44%

basics

~20 s

Keep one proxy mapping pointed at the live meter API, sitting below every recorded stub so it only fires on an uncovered call. Run it on a scheduled job rather than every suite, and make it removable by metadata.

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

In what order would you undo a WireMock ferry fixture's catch-all stub and its --no-request-journal flag?

level: seniorimportance: nice to knowfreq 38%

basics

~20 s

Turn WireMock's request journal back on first. Recording changes no response, so nothing can break, and verify() plus the serve-event list immediately show what the suite really sends. Only then narrow or delete the catch-all mapping, which does change behaviour.

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