skip to content

Specification-Derived Mappings

Mappings the server builds for you out of an artefact you already publish: an OpenAPI document turned into expectations with its own example responses, and bodies generated from a schema.

on this pageshow

explore

questions

4

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

level: middleimportance: must knowfreq 66%

answer

  1. the document already knows the shape
  2. one expectation per selected operation
  3. MockServer's class is OpenAPIExpectation
  4. MockServerClient.upsert takes it as varargs
  5. no withOpenAPI method exists

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.

solid answer

~50 s

In MockServer, `MockServerClient.upsert(OpenAPIExpectation...)` turns a published OpenAPI document into a live expectation set: you hand it an `OpenAPIExpectation` built by the static factory `openAPIExpectation(`, and MockServer walks the document's operations and registers one expectation per operation. The request side of each expectation comes from the operation itself — its method, its path and the parameters and body the document declares — so you never hand-write a matcher for it. The reply comes from the document too: the response the operation declares, using its example where one exists. MockServer's `withSpecUrlOrPayload(` says where the document lives, and its `withOperationsAndResponses(` narrows the set and picks which declared response each operation answers with. There is no `withOpenAPI` method anywhere in MockServer; `upsert(` is the only door. Because the set is derived, a change to the published document changes your mock the next time MockServer's `upsert(` runs.

code

java · 10 lines
java
import org.mockserver.client.MockServerClient;

import static org.mockserver.mock.OpenAPIExpectation.openAPIExpectation;

MockServerClient client = new MockServerClient("localhost", 1080);

// MockServer builds one expectation per operation in the beehive telemetry document
client.upsert(
    openAPIExpectation("org/apiary/openapi/hive-telemetry.yaml")
);

go deeper

for a junior

Be ready to name MockServer's entry point: upsert on MockServerClient, taking an OpenAPIExpectation built by the openAPIExpectation factory. Know that the expectations come out of the OpenAPI document rather than being typed by hand.

for a middle

Explain what MockServer derives per operation: the method, path and declared parameters on the request side, and the declared response on the reply side. Say where the document itself comes from.

for a senior

Show that you know when the document is read. Upsert resolves it once and registers the result, so the expectation set is a snapshot from that moment and later edits to the published document change nothing until you upsert again.

for a principal

Own the question of who publishes the beehive telemetry document and on what cadence, because a derived expectation set inherits that team's release discipline along with their schema, and every consuming suite inherits it too.

## Why derive a mapping set at all A stub server answers a request only because something told it how. Normally that something is a pair you type by hand: a matcher that decides which requests the rule owns, and a response it hands back. For the beehive telemetry API that means writing one rule for `GET /apiaries/{apiaryId}/hives`, another for `GET /hives/{hiveId}/weight`, another for the 503 the ingest tier returns when the queue is backed up — and every one of those facts already exists somewhere else, in the OpenAPI document the apiary platform team publishes. A **specification-derived mapping set** is MockServer reading that document and building the expectations out of it, so the fact is stated once instead of twice. ## The call, in MockServer In MockServer the class is `OpenAPIExpectation` and its static factory is `openAPIExpectation(`. The entry point that installs the result on a running server is `MockServerClient.upsert(OpenAPIExpectation...)`: ```java client.upsert(openAPIExpectation("org/apiary/openapi/hive-telemetry.yaml")); ``` Three details matter more than they look: - MockServer's `upsert(` is **varargs**, so several `OpenAPIExpectation` values load in one call. That is how a split surface comes up together: an apiary registry document alongside a telemetry document. - The document string belongs to the expectation, not to the client. It arrives through the factory, or through MockServer's `withSpecUrlOrPayload(` on an expectation built empty. - **MockServer has no `withOpenAPI` method.** It is the name people reach for by analogy with `withStatusCode(`, `withBody(` and the other `with*` builders on `HttpResponse`, and it is simply not there. MockServer's `upsert(` is the only door. ## What each generated expectation carries For every operation MockServer selects, it registers one expectation: 1. The **request side** is derived from the operation itself: its method, its path, and the parameters and request body the document declares for it. You do not write a matcher, and you cannot forget one. 2. The **reply side** is derived from the response the document declares — the status it names, and the body that response carries. 3. Where the response declares an example, that example is what comes back. Where it declares only a schema, the body is synthesised to satisfy that schema; the same generator is reachable directly as MockServer's `HttpResponse.withGenerateFromSchema(`. The surface involved is small enough to hold in your head: | MockServer surface | what it does | | --- | --- | | `openAPIExpectation(` | static factory that builds an `OpenAPIExpectation` | | `withSpecUrlOrPayload(` | where the document is: a URL, a file or classpath location, or the document inline | | `withOperationsAndResponses(` | maps operation id to the declared response it should answer with, and narrows the set | | `openAPIExpectationWithStringResponses(` | the factory form taking the document together with that operation-to-response map | | `upsert(OpenAPIExpectation...)` | installs the generated expectations on the running MockServer | ## When the document is read MockServer's `upsert(` resolves the document, builds the expectations and registers them. That is the whole of it: afterwards MockServer matches incoming beehive telemetry requests against the **registered expectations**, not against the document. Two consequences follow, and both get missed in interviews: - Editing the published document changes nothing on a running mock until something calls MockServer's `upsert(` again. - If MockServer's `withSpecUrlOrPayload(` names a URL, the expectation set is a snapshot of whatever that host served at the instant `upsert(` ran, so identical test code can build different expectations on different days. ## What it is not - It is **not** a validator. Nothing here checks that the beehive telemetry document is correct beyond what MockServer needs in order to read it. - It is **not** a recorder. Nothing is captured from live traffic; the only input is a published artefact. - It is **not** a hand-written set with nicer ergonomics. You trade per-field control over matchers and bodies for a set that tracks the document. - It is **not** usefully exhaustive by default. A large document generates a large number of expectations that no test cares about, which is exactly what MockServer's `withOperationsAndResponses(` exists to fix. ## Attribution, because the products share this vocabulary Three stub servers in this space all say "stub", "matcher" and "response", and several of their method names differ by a single word. The reply-status setter on a MockServer response is `withStatusCode(`; **in WireMock the same idea is typed by hand as `stubFor(...)` with `aResponse().withStatus(`**. So name the product in the sentence that names the method — "MockServer's `upsert(OpenAPIExpectation...)`", never a bare `upsert(` — because the identifier alone does not tell a listener which server you mean, and on this subject the wrong pairing is a real answer-level mistake rather than a slip of vocabulary.

  • What does MockServer do with an operation whose declared response carries no example?
    It falls back to the schema and synthesises a body that satisfies the declared shape rather than returning nothing. The same generator is reachable directly through MockServer's `HttpResponse.withGenerateFromSchema(`, which takes a JSON schema and builds a conforming body. The result is structurally right and semantically arbitrary: types and required keys hold, but the values carry no meaning an assertion can lean on.
  • Can one upsert call load more than one OpenAPI document?
    Yes. `MockServerClient.upsert(OpenAPIExpectation...)` is varargs, so several `OpenAPIExpectation` instances go in one call. That matters when the beehive telemetry surface is split across documents — an apiary registry document and a telemetry document, say — and a test needs both sets standing at once.
  • Is there a withOpenAPI method on MockServer's expectation builder?
    No. The only OpenAPI door in MockServer is `upsert(OpenAPIExpectation...)` on `MockServerClient`, with the argument built by the static `openAPIExpectation(` factory or by `withSpecUrlOrPayload(`. `withOpenAPI` is a name people invent by analogy with the many `with*` builders on MockServer's `HttpRequest` and `HttpResponse`, and it does not exist.

saying these in an interview costs you the question

  • Names a MockServer withOpenAPI method that does not exist
  • Thinks matchers must still be hand-written after upsert
  • Uses WireMock's withStatus on a MockServer response
  • Assumes MockServer re-reads the document on every request
  • Believes upsert accepts only one document per call
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

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