In MockServer, how do you make one operation of a spec-derived beehive telemetry mock answer 503?
answer
- the document already lists the failures
- pick a response, do not invent one
- map of operation id to response
- MockServer withOperationsAndResponses on OpenAPIExpectation
- listing an operation also selects it
basics
~20 sMockServer'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.
solid answer
~50 sIn MockServer, the selector is `OpenAPIExpectation.withOperationsAndResponses(Map<String, String>)`. Each key is an operation id declared in the beehive telemetry document — `listHiveTelemetry`, `getHiveWeight`, `recordBroodTemperature` — and each value names one of the responses that operation declares, so `getHiveWeight` mapped to `503` makes the weight endpoint answer with the document's own 503 response while `listHiveTelemetry` mapped to `200` keeps the happy path. The map does double duty: it chooses the reply per operation and it narrows the generated set, because only the operations you list get an expectation. That matters when a document covers forty operations and your test cares about two. The value must be a response the operation actually declares — you are picking from the document, not inventing a status — so a failure path nobody wrote into the specification cannot be produced this way. Pair it with MockServer's `withSpecUrlOrPayload(` to say where the document lives.
code
java · 12 linesimport java.util.Map;
import static org.mockserver.mock.OpenAPIExpectation.openAPIExpectation;
client.upsert(
openAPIExpectation()
.withSpecUrlOrPayload("https://apiary.internal/specs/hive-telemetry.yaml")
.withOperationsAndResponses(Map.of(
"listHiveTelemetry", "200",
"getHiveWeight", "503"
))
);go deeper
Know that MockServer can build a mock from an OpenAPI document, and that withOperationsAndResponses is the knob deciding which operations are included and what each one replies with.
Explain that the map keys are operation ids from the document and the values are responses the document already declares, so the map both selects which operations are generated and picks their replies.
Be ready to drive a failure path in a beehive telemetry test without touching the document: name only the operations under test, and point one of them at its declared 503 response.
Own the consequence for the specification itself. If a failure mode is not declared as a response in the document, no spec-derived mock can produce it, which turns error coverage into a publishing decision somebody has to own.
## The knob `OpenAPIExpectation.withOperationsAndResponses(Map<String, String>)` is MockServer's control over a specification-derived set. You build the expectation, tell it where the beehive telemetry document lives with MockServer's `withSpecUrlOrPayload(`, and hand it a map: ```java openAPIExpectation() .withSpecUrlOrPayload("https://apiary.internal/specs/hive-telemetry.yaml") .withOperationsAndResponses(Map.of( "listHiveTelemetry", "200", "getHiveWeight", "503")) ``` Everything about the expectations that come out follows from that map. MockServer also exposes `openAPIExpectationWithStringResponses(`, the factory form that takes the document and that same operation-to-response map in one call. ## The keys are operation ids, not paths Each key names an **operation** the document declares — `listHiveTelemetry`, `getHiveWeight`, `recordBroodTemperature` — and not a URL path. That is deliberate, and it matters for a real surface, because one beehive telemetry path can carry several operations: reading `/hives/{hiveId}/brood-temperature` and writing to it are two operations on one path, and a path-keyed map could not tell them apart. Keying on the operation id keeps them separate, and keeps the map stable when somebody rewrites a path without renaming the operation. ## The values are responses the document already declares Each value names one of the responses that operation declares. Mapping `getHiveWeight` to `503` means: build the expectation for `getHiveWeight`, and make it answer with the 503 response the document already carries. You are **choosing** from the document, not authoring a reply. Three consequences fall out of that: - The failure you want to exercise has to exist in the specification. If nobody declared a 503 on `getHiveWeight`, no spec-derived expectation can produce one — and that is now a publishing problem, not a testing problem. - The body you get back for a failure is only as good as the example somebody wrote for it. Error responses are usually the thinnest part of a document, so a generated 503 body is often close to empty. - Switching which failure a suite exercises becomes a one-word edit in a map rather than a rewritten stub, and it survives later changes to the success body's schema. ## The map is a filter as well as a selector Here is the half that surprises people: **operations you do not list do not get expectations.** A document covering forty beehive telemetry operations, upserted with a two-entry map, produces two expectations. A request to any other path is not matched by this set at all. That is usually exactly what a test wants, but it changes how you read a failure — an unexpected miss may mean the code under test called an operation you never named, rather than that a matcher is wrong. The decision, in order: 1. Name the operations the test actually exercises. 2. Give each one the declared response you want it to answer with. 3. Leave everything else ungenerated, so that if the code under test reaches for it, you find out. Compare MockServer's no-map form, `openAPIExpectation(spec)`, which generates across the document. That form suits a long-running sandbox somebody clicks around in; the map form suits a test that is making a point. ## What the map does not control - It does not change **matching**. The request side of every generated expectation still comes from the operation's own method, path and declared parameters. - It does not invent statuses. A value naming something the operation does not declare is not a way to conjure a new failure mode. - It does not change **when** the document is read: MockServer's `upsert(` resolves the document once and registers the result. - It does not rewrite the body. If you need a specific `weightKg` value in the reply, the derived set is the wrong tool and MockServer's ordinary `response()` builder is the right one. ## Why this is the fidelity question, not a convenience A suite that exercises failure paths through MockServer's `withOperationsAndResponses(` can only ever exercise the failures the beehive telemetry document admits to. That is a genuine benefit and a genuine ceiling in the same sentence: the benefit is that the failure your test drives is one the provider has committed to in writing; the ceiling is that everything the provider forgot to write down is invisible to you. Teams that take this seriously end up treating the error responses in the document as a first-class deliverable rather than an afterthought, because the mock's failure coverage is now a direct function of them. One attribution note, because the vocabulary collides: `withOperationsAndResponses(` and `withSpecUrlOrPayload(` are MockServer's, on `OpenAPIExpectation`, and **WireMock's hand-written equivalent for the same beehive telemetry endpoint would be a `stubFor(...)` with `aResponse().withStatus(503)`** — a different product, a different method name, and no shared class between them.
- In MockServer, what happens to operations you leave out of the withOperationsAndResponses map?They are not generated. The map is a filter as well as a selector, so an operation absent from it has no MockServer expectation and a request to that beehive telemetry path is simply unmatched by this set. That is usually what a focused test wants, and it is a surprise to anyone who expected the whole document to load anyway.
- In MockServer, can withOperationsAndResponses return a status the beehive telemetry document does not declare?No. The values name responses the operation already declares, so you are choosing among the document's own answers rather than inventing one. Producing a status the specification never mentions means writing an ordinary MockServer expectation with `response().withStatusCode(`, outside the derived set entirely.
saying these in an interview costs you the question
- Thinks the map value can be any HTTP status code
- Expects unlisted operations to still get expectations
- Puts the request path, not the operation id, in the key
- Uses WireMock's withStatus to override a generated reply
- Believes a 503 must be hand-written outside the document