skip to content

Incoming Request Criteria

The predicate half of a stub: which parts of an arriving request a server reads before deciding this entry answers it, and which entry wins when two both fit. A wrong match is a silently wrong test.

on this pageshow

explore

questions

18

In WireMock, what does withRequestBody(equalToJson(...)) require of a request body?

level: juniorimportance: must knowfreq 72%

answer

  1. structural, not textual
  2. parsed on both sides before comparing
  3. strict by default in WireMock
  4. two flags: array order, extra elements
  5. invalid JSON never matches at all

basics

~20 s

In WireMock, withRequestBody(equalToJson(...)) parses the request body as JSON and requires it to equal your expected document exactly. Extra fields, missing fields and reordered arrays all make it miss. Two optional flags relax extra elements and array order.

solid answer

~40 s

In WireMock, `equalToJson(` is a *structural* comparison rather than a string one: the body is parsed and compared with the expected document you supplied, so pretty-printing and object key order are irrelevant but the content is not. By default it is strict, so a peatland carbon-survey POST to `/carbon/v1/surveys` that adds a `clientVersion` field your expected document never mentions will not match, and neither will one that omits `siteId` or sends `readings` in a different order. WireMock's three-argument form, `equalToJson(json, true, true)`, switches on `ignoreArrayOrder` and `ignoreExtraElements`; in a mapping file those are sibling keys of `equalToJson`. A body that is not valid JSON never matches at all, because WireMock has no string fallback here. When only one field decides the response, WireMock's `matchingJsonPath(` is usually the better tool than a relaxed whole-document comparison.

go deeper

for a junior

Be able to write withRequestBody(equalToJson(...)) on a WireMock stub and say what it demands: a parsed JSON body equal to the expected document, with formatting and key order irrelevant.

for a middle

Explain the mechanics: WireMock parses both sides, arrays are ordered so order counts, types are part of the value, and the three-argument overload exposes the only two tolerances there are.

for a senior

Show when strict whole-document matching is the wrong instrument, and be ready to justify ignoreArrayOrder per endpoint rather than switching it on everywhere out of habit.

for a principal

Own the default your teams write stubs against and the review rule that goes with it, including who is allowed to pin a whole payload and what that commits the team to maintaining.

## What "equal" means to WireMock's `equalToJson(` WireMock's `equalToJson(` is a **structural** JSON comparison. When a request arrives, WireMock parses the body into a JSON tree and compares it with the tree parsed from the expected document you passed in. Everything that follows is a consequence of that one design decision: - Formatting is irrelevant. Indentation, line breaks and spacing are gone before the comparison. - Object key order is irrelevant, because a JSON object is an unordered set of members. - Array order **is** relevant by default, because a JSON array is ordered. - Numbers compare as numbers, so `-12` and `"-12"` are different; type is part of the value. - A body that fails to parse as JSON does not match. WireMock does not fall back to string equality. ## The default is strict, and strict means strict The peatland carbon-survey API in this leaf accepts a submission at `POST /carbon/v1/surveys`: ```json { "siteId": "PEAT-114", "readings": [ { "plotId": "PLOT-7", "waterTableCm": -12 } ] } ``` A WireMock stub written as `post(urlPathEqualTo("/carbon/v1/surveys")).withRequestBody(equalToJson(expected))` matches a body with exactly those members and nothing else. Each of the following stops it matching, and every one of them is a change a real client makes without telling you: - the survey app starts stamping a `clientVersion` field into every submission; - the app stops sending `waterTableCm` for a plot with no standing water; - the `readings` array arrives sorted by plot instead of by sample time; - `waterTableCm` arrives as the string `"-12"` rather than the number `-12`. The first and third of those are the ones the tolerance flags exist for. The second and fourth are not, and that asymmetry is the single most useful thing to know about this matcher. ## The two tolerance flags WireMock's `equalToJson(` has a three-argument overload, `equalToJson(String json, Boolean ignoreArrayOrder, Boolean ignoreExtraElements)`: - In WireMock, `ignoreArrayOrder` removes the significance of position inside arrays, so `readings` may arrive in any sequence. - In WireMock, `ignoreExtraElements` forgives content present in the arriving body but absent from your expected document, which turns the comparison into "the expected document is contained in what arrived". In a WireMock mapping file the same two knobs are sibling keys of `equalToJson` rather than positional arguments: ```json { "request": { "method": "POST", "urlPath": "/carbon/v1/surveys", "bodyPatterns": [ { "equalToJson": { "siteId": "PEAT-114" }, "ignoreExtraElements": true, "ignoreArrayOrder": true } ] }, "response": { "status": 202 } } ``` ## The same job in the other two servers This is where attribution matters, because the three servers start from different defaults for the same mechanism: | Server | Default for a JSON body matcher | How you change it | |---|---|---| | WireMock | strict: `equalToJson(` requires the documents to correspond | pass `ignoreExtraElements` and `ignoreArrayOrder` | | MockServer | tolerant: `json(` uses `MatchType.ONLY_MATCHING_FIELDS` | pass `MatchType.STRICT` | | Mountebank | depends on the predicate you choose from its eleven | `equals` compares what you named, `deepEquals` the whole structure | Reading that table the wrong way round is a real interview trip-hazard: someone who learned MockServer first will expect a WireMock `equalToJson(` to ignore fields it was not told about, and someone who learned WireMock first will expect MockServer's `json(` to be strict. Neither default is wrong; they are simply opposite. ## How to pick the matcher, in order 1. Decide what actually selects the response. If it is one or two fields, use WireMock's `matchingJsonPath(` and stop. 2. If the shape of the whole document is the point, use WireMock's `equalToJson(` with `ignoreExtraElements` on, so additive upstream changes do not break the stub. 3. Turn WireMock's `ignoreArrayOrder` on only where the API itself treats order as insignificant. Turning it on reflexively hides a real ordering bug. 4. Leave both flags off only when the exact payload is the thing under test and a reviewer agrees. ## Traps worth naming - Believing WireMock's `equalToJson(` compares raw strings, and worrying about whitespace. - Believing it ignores unmentioned fields. That is MockServer's default, not WireMock's. - Expecting a non-JSON body to fall back to a text comparison; in WireMock it simply does not match. - Assuming WireMock's `ignoreExtraElements` also forgives fields the client stopped sending. It does not. - Reaching for a relaxed whole-document matcher when a single WireMock `matchingJsonPath(` would say exactly what the stub means. The short version a candidate should be able to give under time pressure: WireMock's `equalToJson(` parses both sides and demands they correspond, the two flags relax additions and ordering only, and everything else about the payload is still an assertion the stub is making.

  • Where do ignoreArrayOrder and ignoreExtraElements go in a WireMock JSON mapping file?
    They are sibling keys of WireMock's `equalToJson` inside the same body pattern object, not nested under it and not positional. The mapping form and the Java three-argument overload express the same thing, so a stub recorded to disk and a stub written in code behave identically.
  • Does a WireMock equalToJson stub care whether the request declares a JSON content type?
    The matcher itself works on the body: it tries to parse what arrived and fails to match if it cannot. If you also want to require the header, add that as a separate header predicate on the stub. Relying on a content type to imply the body shape is how a stub ends up matching a payload nobody meant it to.

saying these in an interview costs you the question

  • Says equalToJson compares the body as a raw string
  • Thinks WireMock ignores fields the expected document omits
  • Expects a non-JSON body to fall back to text comparison
  • Believes object key order affects the comparison
  • Assumes ignoreExtraElements also forgives missing fields
open as a page

In MockServer, how do you match only requests that are missing an `X-Sweep-Tenant` header?

level: middleimportance: must knowfreq 57%

basics

~20 s

Negate the header name. MockServer holds request names and values as NottableString values, so a header built from not("X-Sweep-Tenant") matches only calls that carry no such header. Negating the value instead matches a header that is present but different.

open as a page

In MockServer, does an expectation naming one query-string parameter still match a request that sends three?

level: middleimportance: must knowfreq 68%

basics

~20 s

Yes. MockServer matches on a subset, not on equality. Every header, cookie and query-string parameter you name is a constraint the request must satisfy; every one you do not name is ignored, however many the client sends.

open as a page

In WireMock, why does raising a stub's atPriority() number make it lose, not win?

level: middleimportance: must knowfreq 70%

basics

~20 s

Because WireMock sorts matching stubs by priority ascending and serves the first one, so the number is a place in a queue rather than a strength. Raising it moves the stub further back, behind the default five.

open as a page

A WireMock weight-log stub stopped answering after a teammate added a mapping. Why?

level: seniorimportance: must knowfreq 58%

basics

~20 s

Nothing about your stub changed. The new mapping also matches those requests and sorts ahead of yours, either by carrying a lower atPriority number or by arriving later at equal priority. Your stub still matches; it is no longer first.

open as a page

In WireMock, how do any() and anyUrl() widen a stub, and what does each leave unconstrained?

level: seniorimportance: must knowfreq 55%

basics

~20 s

In WireMock, any() is a request-pattern builder that accepts every HTTP method while still applying the URL matcher you give it. WireMock's anyUrl() is a URL matcher that accepts every URL. Together they widen two separate axes.

open as a page

In MockServer, what does `withQueryStringParameter("borough", "camden")` add to an expectation?

level: juniorimportance: should knowfreq 61%

basics

~20 s

It adds a predicate to the expectation's request side. The call matches only if the URL query string carries a borough parameter whose value matches camden. A request without that parameter is simply not matched by this expectation.

open as a page

In WireMock, what does atPriority() set on a stub, and what is the default?

level: juniorimportance: should knowfreq 64%

basics

~20 s

WireMock's atPriority sets a stub's precedence number. A stub that never calls it sits at DEFAULT_PRIORITY, which is five. Lower numbers win, so among several matching stubs WireMock serves the lowest-numbered one, whatever order they were registered in.

open as a page

In WireMock, how do urlEqualTo() and urlPathEqualTo() differ when a query string is present?

level: juniorimportance: should knowfreq 72%

basics

~20 s

WireMock's urlEqualTo matches the whole request URL, path and query string together. WireMock's urlPathEqualTo matches the path alone and ignores everything after the question mark. Add a query parameter and the urlEqualTo stub stops matching, while urlPathEqualTo still fires.

open as a page

In WireMock, which of two equal-priority stubs serves a request they both match?

level: middleimportance: should knowfreq 55%

basics

~20 s

At equal priority WireMock serves the stub registered most recently, because it sorts matching stubs by priority ascending and then by insertion index descending. Newest-wins is only the tie-break. A later stub with a weaker priority number still loses.

open as a page

In WireMock, how does a stub pin the HTTP method, and why is withMethod() not it?

level: middleimportance: should knowfreq 56%

basics

~20 s

In WireMock the method is chosen by the request-pattern builder itself — get, post, put, delete, patch or any — each taking a URL matcher. WireMock's withMethod belongs to its webhook and logged-request builders, not to stub matching at all.

open as a page

In WireMock, what does equalToJson() still reject when ignoreExtraElements and ignoreArrayOrder are on?

level: seniorimportance: should knowfreq 52%

basics

~20 s

In WireMock, ignoreExtraElements and ignoreArrayOrder forgive only additions and array order. A missing field, a changed value or a different JSON type still makes WireMock's equalToJson miss, and so does a body that is not valid JSON at all.

open as a page

In WireMock, when does matchingJsonPath() beat equalToJson() for a large peatland survey body?

level: seniorimportance: should knowfreq 55%

basics

~20 s

In WireMock, matchingJsonPath selects part of a body with a JSONPath expression and matches when the expression returns something. The rest of the payload may vary freely. Use it when one field decides which canned response the stub returns.

open as a page

In MockServer, why does `withHeader("X-Sweep-Tenant", "acme.co")` also match a request sending `acmeXco`?

level: seniorimportance: should knowfreq 38%

basics

~20 s

MockServer compares a header value literally first, then retries it as a regular expression. The dot in acme.co is therefore a wildcard that any character satisfies, so acmeXco matches as well. Escape the metacharacter to pin the value.

open as a page

How would you set a WireMock body-matching strictness policy across many peatland survey stub sets?

level: principalimportance: should knowfreq 46%

basics

~20 s

Default to WireMock's equalToJson with ignoreExtraElements on, so stubs survive additive payload changes, and use matchingJsonPath for the one or two fields that actually select the response. Reserve strict whole-body equality for the few endpoints whose entire payload genuinely matters.

open as a page

What convention would you set for WireMock atPriority() numbers in a large stub set?

level: principalimportance: should knowfreq 42%

basics

~20 s

Reserve narrow bands around WireMock's default of five: a low band for deliberate overrides, the untouched default for ordinary stubs, and a high band for fallbacks. Require every explicit atPriority number to name the mapping it outranks.

open as a page

In WireMock, when do you match a peatland survey XML body with matchingXPath() instead of equalToXml()?

level: middleimportance: nice to knowfreq 36%

basics

~20 s

In WireMock, equalToXml compares the whole request document, so any element the client adds breaks the stub. WireMock's matchingXPath selects one node instead and matches when it exists. Use XPath when only part of the XML decides the response.

open as a page

In WireMock, what does urlPathTemplate() match, and what does withPathParam() add?

level: middleimportance: nice to knowfreq 42%

basics

~20 s

WireMock's urlPathTemplate matches a request path against a template such as /bindery/v2/orders/{orderId}, ignoring the query string. Each placeholder becomes a named variable. WireMock's withPathParam then constrains one of those variables with a value matcher such as equalTo or matching.

open as a page