skip to content

In WireMock, what do aResponse(), withStatus() and withBody() each set on a stubbed reply?

level: juniorimportance: should knowfreq 68%

answer

  1. three parts: status, headers, body
  2. the reply starts at aResponse()
  3. nothing is copied from the request
  4. WireMock spells it withStatus, not withStatusCode
  5. withStatusCode belongs to MockServer's response()

basics

~20 s

In WireMock, aResponse() starts the response builder, withStatus sets the numeric HTTP status, and withBody sets the literal reply body as text. WireMock adds response headers separately, through withHeader. Nothing in the reply is inferred from the request.

solid answer

~50 s

In WireMock a stub's reply is assembled by `aResponse()`, which returns a `ResponseDefinitionBuilder` on which every part of the answer is set explicitly. WireMock's `withStatus(int)` sets the status code — `aResponse().withStatus(503)` stands in for the allotment water main being shut off — and WireMock's `withBody(String)` writes a literal string as the body bytes, with `withJsonBody(` taking an already-parsed JSON node instead. WireMock's `withHeader(` adds one response header per call and `withStatusMessage(` sets the reason phrase; none of them are derived from the request that matched. The trap worth memorising is the spelling: WireMock's setter is `withStatus(`, while MockServer's equivalent on `response()` is `withStatusCode(Integer)`, so `aResponse().withStatusCode(200)` mixes two products and exists in neither. A stub that sets a body and no `Content-Type` header is still valid in WireMock; the client simply receives bytes with no declared media type.

go deeper

for a junior

Be ready to write a three-line stub from memory: aResponse(), then withStatus, then withBody. Know that response headers are a separate withHeader call and that WireMock's default status is 200.

for a middle

Explain that the response definition is a builder with no knowledge of the request, and name the other body setters WireMock offers: withJsonBody, withBodyFile and withBase64Body. Say what each one is for.

for a senior

Show that you keep attribution straight across stub servers: WireMock's withStatus versus MockServer's withStatusCode. Mixing them is the defect that passes code review because both names are real somewhere.

for a principal

Own the convention: decide as a team whether payloads live inline or in files, and whether every stub must declare Content-Type. Consistency here is what keeps a large stub set reviewable by people who did not write it.

## What a canned reply is made of A WireMock stub has two halves. The request pattern decides **whether** the stub answers a given call; the response definition says **what** the answer is. WireMock builds that second half with `aResponse()`, a static factory that returns a `ResponseDefinitionBuilder`, and every field of the reply is placed on that builder by an explicit call. Nothing is derived — WireMock does not read the matched URL, the incoming headers or the request body and synthesise an answer out of them. That is why two stubs on an allotment water-rota API that differ only in the plot they answer for each carry their own literal body. The literal-reply surface WireMock puts on that builder: - `withStatus(int)` — the numeric status code; `aResponse().withStatus(503)` is the stub standing in for the site's water main being shut off. - `withStatusMessage(String)` — the reason phrase that travels beside the code on the status line. - `withHeader(String, String...)` — one response header per call; a JSON reply declares its `Content-Type` here. - `withBody(String)` — the body as a literal string, stored in the mapping itself. - `withJsonBody(` — the body taken from an already-parsed JSON node, for a fixture the test assembled in memory. - `withBase64Body(` — arbitrary bytes, carried inside the mapping as base64 text. - `withBodyFile(` — the body read from a named file under `__files` instead of from the mapping. WireMock's builder starts at status 200, so a response definition that never calls `withStatus(` still answers 200; every other field stays empty until you set it. ## The identifier trap this leaf exists to defuse WireMock's status setter is `withStatus(`. In MockServer the equivalent setter is `withStatusCode(Integer)`, on the object MockServer's `response()` returns. Both spellings are real and each belongs to a genuine API, so a sentence that pairs one product's builder with the other product's setter reads perfectly and is false — it compiles in neither product, and it survives any review that only asks *is this a real method name somewhere*, because both halves are real names somewhere. The same shape catches people on the file-backed body: WireMock's HTTP builder spells it `withBodyFile(`, while in MockServer the same idea is spelled `withBodyFromFile(`. The habit that protects you is small and mechanical — **name the product in the same sentence as the identifier, every time you write one down**. ## Three products, one vocabulary | product | reply builder | status | inline body | body from a file | |---|---|---|---|---| | WireMock | `aResponse()` | `withStatus(int)` | `withBody(String)` | `withBodyFile(` | | MockServer | `response()` | `withStatusCode(Integer)` | `withBody(...)` | `withBodyFromFile(` | | Mountebank | the `"is"` response type | a `statusCode` field | a `body` field | — | Mountebank's shape differs as well as its spelling. In Mountebank an `is` response is a literal object written straight into the imposter's stub array, and Mountebank's imposter-level `defaultResponse` supplies the fields an individual `is` response leaves out. ## Why "nothing is inferred" is the whole point A literal reply is the least clever thing a stub server can do, and that is its value: 1. **It is exact.** The bytes a water-rota client sees are the bytes somebody typed. There is no rendering step to debug when the reply is wrong, only a string to read. 2. **It is cheap to review.** A reviewer looking at a WireMock mapping sees the status, the headers and the payload in one place and can judge whether the fake matches the real service. 3. **It is a promise you keep by hand.** Because WireMock copies nothing from the request, a literal body drifts silently when the real allotment API adds a field. Keeping the two aligned is a maintenance job, not something the server does for you. The moment a body needs to change with the request, you have left this mechanism: that is a different feature of the server and a different subject. ## Getting the three parts right in practice - Set the status first — a stub with no `withStatus(` call in WireMock is a 200 stub whether you meant it or not. - Set `Content-Type` with WireMock's `withHeader(` whenever the body is JSON, XML or anything a client will parse; the body call alone declares no media type. - Keep the payload small enough to read inside the mapping, and move it to `withBodyFile(` when it stops being readable. - Use `withStatusMessage(` only for the reason phrase, never as a place to smuggle body text. - Write each stub's payload in full rather than sharing one mutable object between stubs; two mappings that must differ should look different on the page. ## What an interviewer is listening for - That you name the builder: a WireMock reply starts at `aResponse()`, not at the stub or the matcher. - That the status, the headers and the body are three separate calls in WireMock, never one combined setter. - That you spell the setter belonging to the product you are naming, and do not blend WireMock's `withStatus(` with MockServer's `withStatusCode(`. - That you can say what a literal reply cannot do, and name the boundary rather than reaching for the wrong tool. A candidate who can build a correct three-line water-rota stub and then explain why WireMock ignores the request when producing it has understood the mechanism, not just the syntax.

  • What does a WireMock stub answer if the response definition never calls withStatus()?
    It answers 200. WireMock's `ResponseDefinitionBuilder` starts at that status, so `aResponse().withBody("...")` is a 200 reply with a body. That is convenient for a happy-path water-rota stub and a hazard for an error stub, because forgetting `withStatus(503)` produces a green test against a success reply you never intended to define.
  • How would you make a WireMock stub return JSON that a strict client will actually deserialise?
    Set the media type explicitly: `aResponse().withStatus(200).withHeader("Content-Type", "application/json").withBody(...)`. WireMock sends the headers the stub defines, so a client that inspects `Content-Type` before parsing will reject an otherwise perfect body when the header is missing. Adding the header is one call and removes a whole class of confusing failures.

saying these in an interview costs you the question

  • Calling withStatusCode on WireMock's aResponse() builder
  • Assuming WireMock copies request headers into the reply
  • Believing withBody also sets a Content-Type header
  • Thinking withStatus takes a status name rather than a number
  • Saying WireMock derives the body from the matched URL