In MockServer, what does withSpecUrlOrPayload() accept, and what changes when you point it at a URL?
answer
- one string, three meanings
- the name spells out both options
- URL, file or classpath, or inline document
- resolved when upsert runs, not per request
- currency versus a reproducible build
basics
~20 sMockServer'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.
solid answer
~50 s`OpenAPIExpectation.withSpecUrlOrPayload(String)` in MockServer takes one string and interprets it three ways: a URL to fetch, a file or classpath location to read, or the OpenAPI document itself, inline as JSON or YAML. Which one you pick decides where your beehive telemetry mock's truth lives. A URL — say the apiary platform team's published `hive-telemetry.yaml` — is resolved when MockServer's `upsert(` runs, so the expectation set is a snapshot of whatever that host served at that instant, the run now needs that host reachable, and two identical test runs on different days can build different expectations. A classpath copy committed alongside the tests makes the run reproducible and offline, at the cost of being exactly as current as the last time somebody refreshed it. The tension is currency versus reproducibility, and the argument to MockServer's `withSpecUrlOrPayload(` is where you settle it.
go deeper
Know that MockServer's withSpecUrlOrPayload is where the OpenAPI document comes from, and that it takes a URL, a file or classpath location, or the document itself as a string.
Explain the timing. The string is resolved when upsert runs, not on each request, so the expectation set is fixed at that point and stays fixed until something upserts again.
Be ready to argue the tradeoff for a real pipeline. A URL keeps the beehive telemetry mock current and makes the build depend on a host you do not own; a committed copy does the opposite, and the choice differs between a merge gate and a drift-watching job.
Own the policy across repositories: which suites may fetch a live document, which must pin one, how a pinned copy gets refreshed on a cadence somebody actually owns, and how a build records which document it was built from.
## One string, three meanings MockServer's `OpenAPIExpectation.withSpecUrlOrPayload(String)` is unusually honest for a method name: it says outright that its single argument is either a **spec URL** or a **payload**. In practice it covers three inputs: - a **URL** the server fetches, typically the published beehive telemetry document on an internal host; - a **file or classpath location** it reads, such as `org/apiary/openapi/hive-telemetry.yaml` packaged with the tests; - the **document itself, inline**, handed over as a JSON or YAML string — useful for a fragment written for one test rather than a whole surface. The same string also reaches MockServer's `openAPIExpectation(` when you use the factory form, so this choice exists whichever way you build the expectation. Nothing else about the derived set changes: the request side of each expectation still comes from the operation, and the reply side still comes from the response the document declares. ## When it is resolved This is the part that decides everything downstream. `MockServerClient.upsert(OpenAPIExpectation...)` resolves the string, builds the expectations and registers them. From that moment MockServer matches incoming beehive telemetry requests against the **registered expectations**, not against the document. So: - The document is read **once per upsert**, not once per request. - Editing the published document changes nothing on a running mock until something calls MockServer's `upsert(` again. - Whatever the source served at that instant is what your suite is testing against, for the rest of the run. ## The URL form: current, and not reproducible Pointing at `https://apiary.internal/specs/hive-telemetry.yaml` means your mock is built from whatever the apiary platform team published most recently. That is the appealing property and the whole reason this leaf exists: the expectation set tracks the document instead of tracking your memory of it. It buys that with three costs that show up in a pipeline rather than on a laptop: 1. **A runtime dependency on a host you do not own.** If it is unreachable or slow, the mock is never built and every test that needed it fails for a reason unrelated to the code under test. 2. **Non-reproducibility.** Identical test code, identical commit, two different days, potentially two different expectation sets. A red build cannot be reasoned about from the commit alone. 3. **A silent behaviour change.** Nobody on your team edited anything, and the mock behaves differently, because somebody on another team edited the document. ## The pinned form: reproducible, and only as fresh as its last refresh A copy of the document committed on the classpath inverts every one of those. The run is offline, hermetic and reproducible; a red build is explained by the commit. The cost is stated plainly rather than hidden: the copy is exactly as current as the last time a person refreshed it, and that refresh has to be somebody's job or it does not happen. This is the honest version of the tradeoff, and it is worth saying in an interview in exactly these terms: - A URL keeps the mock **current** and makes the build depend on a host outside your control. - A committed copy makes the build **reproducible** and makes currency a scheduled human act. - An inline payload makes a single test **self-contained** and does not scale past a fragment. ## Choosing, in a real repository Most teams that have lived with this land on a split rather than a rule: pinned copies in the suites that gate a merge, because a merge gate must be reproducible, and a URL in a separate, non-gating job whose entire purpose is to notice that the published document moved. The second job is allowed to be red for a reason unrelated to your commit, because that is what it is for; the first is not. What you should be able to state, either way, is who owns the refresh, and what the expectation set was built from on the run you are looking at. A build log that does not record which document produced the expectations is a build you cannot debug later. One attribution note, since three servers share this vocabulary: `withSpecUrlOrPayload(` is MockServer's, on `OpenAPIExpectation`, and it is a member of the same small family as `withOperationsAndResponses(`. **In WireMock the same beehive telemetry stubs are typed by hand with `stubFor(...)` and `aResponse()`**, so a sentence about deriving an expectation set from a published document is a MockServer sentence and should name MockServer.
- When exactly does MockServer read the document named by withSpecUrlOrPayload?When MockServer's `upsert(` runs. The call resolves the string, builds the expectations and registers them; incoming requests are then matched against the registered expectations rather than against the document. Editing the published beehive telemetry document afterwards changes nothing until something calls MockServer's `upsert(` again.
- In MockServer, what breaks in a pipeline when withSpecUrlOrPayload points at an internal URL?The suite acquires a runtime dependency on that host. If it is unreachable or slow, the mock never gets built and every test that needed it fails for a reason unrelated to the code under test. Worse, the same commit can produce different expectation sets on different days, so a red build cannot be reasoned about from the commit alone.
- Is an inline OpenAPI payload ever the right argument?For a fragment, yes. A handful of operations written into the test as a YAML or JSON string keeps that test entirely self-contained, with no file to find and no host to reach. It stops being right the moment the fragment starts duplicating a document the apiary platform team already publishes.
saying these in an interview costs you the question
- Thinks the argument must always be a URL
- Assumes MockServer re-fetches the URL on every request
- Cannot say when the document is actually read
- Says a URL-backed mock is reproducible across days
- Confuses the argument with a filesystem-only path