skip to content

Canned Replies

Once a request matches, what actually goes back: a fixed status, headers and body, a body computed from the request, or a different answer each time. Interviewers probe how canned your data really is.

on this pageshow

explore

questions

13

In WireMock, why does a stubbed body containing `{{request.path}}` come back unrendered?

level: juniorimportance: must knowfreq 66%

answer

  1. rendering is opt-in, not automatic
  2. the body was served, not interpreted
  3. something must name the transformer
  4. WireMock resolves response-template exactly
  5. WireMock withTransformers, or the global flag

basics

~20 s

WireMock renders a stub body only when the response-template transformer is attached to that response. Without it, WireMock treats the body as literal bytes and returns the Handlebars source unchanged. Attach it with withTransformers, or launch WireMock with --global-response-templating.

solid answer

~40 s

Response templating in WireMock is opt-in per response, not a global default. A WireMock response definition renders Handlebars only when the `response-template` transformer is attached to it, so a body written as a template but served without that attachment goes out byte for byte and the caller receives the literal characters `{{request.path}}`. Attach it in WireMock's Java DSL with `aResponse().withBody(...).withTransformers("response-template")`, or in a WireMock JSON stub mapping with `"transformers": ["response-template"]` inside the `response` object rather than beside it. WireMock never warns you about this: it does not scan bodies for braces, so an unrendered template is a perfectly valid 201 carrying a payload the client cannot use. If a whole standalone instance is dynamic, start WireMock with `--global-response-templating`; `--local-response-templating` is WireMock's explicit name for the opt-in default you already have.

go deeper

for a junior

Be ready to say that WireMock templating is opt-in and to name the string response-template. Knowing that a missing transformer produces a literal body rather than an error is the whole first-screen answer.

for a middle

Explain the mechanics: where the transformer name goes in the Java DSL and in a JSON mapping, that rendering happens after matching, and that WireMock gives no warning when a template is served unrendered.

for a senior

Show how you would diagnose it on a running instance — read the mapping back, check the exact spelling, then check how the server was launched — and say why silence rather than an error is the dangerous part.

for a principal

Own the instance-wide choice: whether a shared WireMock renders every response by default or opts in per stub, and what that decision costs a team whose fixture bodies legitimately contain braces.

## What response templating is A WireMock stub mapping has two halves: a request pattern that decides which calls it answers, and a response definition that says what comes back. By default that response definition is inert — the bytes you handed to WireMock's `aResponse().withBody(...)` are the bytes written to the socket. That is the right default. Most stubs want a fixed payload, and a server that tried to interpret every body would mangle the ones that legitimately contain braces. Response templating is the opt-in that changes it. When a WireMock response is templated, the server passes the body and the header values through **Handlebars** before sending them, so a body written as `{"acceptedPath": "{{request.path}}"}` leaves the server as `{"acceptedPath": "/dispatch/v1/assignments"}`. The component that performs this in WireMock is `ResponseTemplateTransformer`, and the name a mapping refers to it by is the exact string **`response-template`**. ## Why a template comes back as text There is one cause worth checking before any other: the transformer is not attached to that response. WireMock does not sniff bodies for `{{`, it does not log a warning when a body looks like an unrendered template, and it does not fail the request. WireMock answers with the status you asked for and a payload containing the literal characters `{{request.path}}`. Downstream that surfaces as a deserialisation failure or, worse, as those braces being stored as a snowplough route identifier. The attachment goes missing in four recognisable ways: - The WireMock Java DSL chain stops one call early: `aResponse().withBody(...)` with no `.withTransformers("response-template")` after it. - A WireMock JSON stub mapping carries `"transformers": ["response-template"]` at the top level of the mapping instead of inside its `response` object, which is where the server looks. - The name is spelled `responseTemplate`, `response_template` or `ResponseTemplateTransformer`, none of which WireMock resolves, because it matches the transformer by that one exact string and renders nothing otherwise. - The mapping is fine, but it was written for a WireMock instance launched with `--global-response-templating` and is being served by one running the opt-in default. ## Attaching it, in both dialects In WireMock's Java DSL the switch is one call on the response builder: ```java stubFor(post(urlPathEqualTo("/dispatch/v1/assignments")) .willReturn(aResponse() .withStatus(201) .withBody("{{request.path}} accepted") .withTransformers("response-template"))); ``` In a WireMock JSON mapping it is an array inside the response object: ```json { "request": { "method": "POST", "urlPath": "/dispatch/v1/assignments" }, "response": { "status": 201, "body": "{{request.path}} accepted", "transformers": ["response-template"] } } ``` Both forms say the same thing to the same component, and neither of them changes matching. Templating decides what the reply contains; it never decides which stub answers. ## Per stub, or for the whole server Two WireMock standalone flags set the default for an instance: 1. `--global-response-templating` makes every response that WireMock instance serves render. It suits an instance whose entire mapping set is dynamic, and it removes the per-mapping noise of repeating the transformer name in every file. 2. `--local-response-templating` states WireMock's opt-in default out loud: a response renders only if it asked to. It is the safer setting for a mixed set, because a fixture body that legitimately contains `{{` — a page fragment, a configuration document, some other tool's template — is then served untouched. Deciding this once per instance is cheaper than rediscovering it per stub, and the choice belongs in whatever starts the server, not in the mappings. ## The same idea, three different shapes | Server | How a reply becomes dynamic | What people get wrong | |---|---|---| | WireMock | attach the `response-template` transformer to the response, or launch with `--global-response-templating` | the transformer is simply not attached, so the Handlebars source ships as data | | MockServer | build the reply as a template with `HttpTemplate.template(TemplateType.VELOCITY, ...)` instead of a literal `response()` | there is nothing to attach — a template and a literal reply are different kinds of response | | Mountebank | add `decorate`, `copy` or `lookup` to that response's `behaviors` array | quoting `repeat` as a behavior, when it is a field on the response and not one of the five behaviors | The first row is the one this question turns on. WireMock is the server of the three where a perfectly well-formed template can be defined and then never run, because the decision to render lives somewhere other than the body itself. ## Diagnosing it in three steps 1. Fetch the mapping back from the running WireMock instance and look for the transformer name inside the `response` object. If it is absent, that is the whole bug. 2. If it is present, compare the spelling with WireMock's `response-template` character by character; a near miss registers no transformer and produces exactly the same symptom. 3. If both are right, check how the instance was launched — a mapping that quietly relies on `--global-response-templating` behaves differently on a WireMock instance that never got the flag.

  • Where exactly does the transformers array go in a WireMock JSON stub mapping?
    Inside the `response` object, alongside `status` and `body` — not at the top level of the mapping and not inside `request`. WireMock reads transformer names off the response definition, because templating is a property of the reply, so a correctly spelled array in the wrong place is ignored in silence and looks identical to having forgotten it.
  • Does WireMock templating apply to anything other than the response body?
    Yes — with the `response-template` transformer attached, WireMock renders response header values as well as the body, so a stub can echo a correlation id from the request into a reply header. Matching is untouched: the request pattern that selects the stub is evaluated before any rendering happens.
  • What is the risk of turning on WireMock's --global-response-templating everywhere?
    Every response on that WireMock instance is then parsed as Handlebars, including bodies that contain braces for their own reasons. A fixture that is itself a template, or a document with `{{` in it, stops coming back verbatim. Global templating is right when the whole set is dynamic and a liability when it is mixed.

saying these in an interview costs you the question

  • Assumes WireMock renders any body that contains double braces
  • Puts a WireMock mapping transformers array beside the response, not inside it
  • Thinks an unrendered template makes WireMock fail the request
  • Spells the transformer responseTemplate and expects WireMock to resolve it
  • Believes templating changes which WireMock stub matches the request
open as a page

In WireMock, how do you make one dive-log endpoint answer PENDING first and SIGNED on the next call?

level: middleimportance: must knowfreq 70%

basics

~20 s

Put both WireMock stubs into one scenario with inScenario. The first requires the start state and calls willSetStateTo to move the conversation on. The second requires that new state and answers only once the first has served.

open as a page

In WireMock, what does aResponse().withBase64Body() serve that withBody(String) cannot?

level: middleimportance: must knowfreq 46%

basics

~20 s

It serves raw bytes. WireMock's withBase64Body takes a base64-encoded string and decodes it into the exact body bytes, so a binary payload such as a signed watering permit survives, while withBody takes text that must go through a character encoding.

open as a page

In WireMock, how do you build a stubbed reply out of the request that triggered it?

level: middleimportance: must knowfreq 62%

basics

~20 s

Attach WireMock's response-template transformer, then reference the request model from the body. WireMock exposes the call as request, so request.path, request.query and request.body are readable, and the jsonPath helper pulls a single field out of a JSON payload.

open as a page

When should a WireMock stub's water-rota body move from withBody() to withBodyFile()?

level: seniorimportance: must knowfreq 58%

basics

~20 s

Move it once the payload buries the matcher, when several mappings need the same fixture, or when the bytes want to be a real file. WireMock's withBodyFile names a file under __files, leaving the mapping with the matcher and status.

open as a page

Your WireMock water-rota stub returns valid JSON but the client refuses to parse it — why?

level: seniorimportance: must knowfreq 55%

basics

~20 s

Almost always the stub set a body and no media type. In WireMock the reply carries only the headers the response definition declares, so a client that checks Content-Type before decoding rejects a perfectly correct body. Add withHeader explicitly.

open as a page

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

level: juniorimportance: should knowfreq 68%

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.

open as a page

In WireMock, how do you give each stubbed dispatch reply a fresh id and timestamp?

level: juniorimportance: should knowfreq 50%

basics

~20 s

WireMock's randomValue helper generates a value such as a UUID, and its now helper renders the current time, with optional offset and format. Both need the response-template transformer attached, or WireMock serves the raw helper text itself as the body.

open as a page

In WireMock, what state does every scenario begin in, and what is Scenario.STARTED really?

level: middleimportance: should knowfreq 56%

basics

~20 s

Every WireMock scenario begins in the state named Started. Scenario.STARTED is a String constant holding exactly that text, not an enum value, so the comparison is literal. A stub waiting on STARTED in capitals therefore never fires.

open as a page

In WireMock, why can two dive-log endpoints sharing one scenario name break each other?

level: seniorimportance: should knowfreq 48%

basics

~20 s

A WireMock scenario name identifies one shared state machine. Every stub naming it reads and writes the same state, so two unrelated dive-log conversations advance each other. A stub waiting on a state the other side consumed then never serves.

open as a page

When should a WireMock stub server run --global-response-templating rather than per-stub templating?

level: seniorimportance: should knowfreq 48%

basics

~20 s

Turn on WireMock's --global-response-templating when every mapping on that instance is dynamic and repeating the transformer name is pure noise. Keep per-stub templating for a mixed set, because global rendering parses every body, including ones that legitimately contain braces.

open as a page

In WireMock, why does a templated body render " where a quote should be?

level: seniorimportance: should knowfreq 44%

basics

~20 s

Handlebars escapes double-brace output for HTML, so WireMock turns a quote into the " entity. In WireMock, the triple-brace form emits the helper's output raw instead. Use it whenever a WireMock template injects JSON or XML into a reply.

open as a page

In Mountebank, how does one stub answer the same dive-log request differently each call?

level: juniorimportance: nice to knowfreq 40%

basics

~20 s

Mountebank cycles a stub's responses array: each matching request takes the next entry, and the sequence wraps at the end. The repeat field on a response holds that entry for several calls. repeat is a response field, not a behavior.

open as a page