skip to content

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

level: principalimportance: should knowfreq 42%

answer

  1. the number is global, not test-scoped
  2. most stubs need no number at all
  3. reserve bands above and below the default
  4. an explicit number is a claim about overlap
  5. never tune a number until green

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.

solid answer

~50 s

The number is global, unscoped and invisible at the point a request arrives, so a convention has to make it readable. I would start from **most stubs carry no number at all** — leaving them on `DEFAULT_PRIORITY`, which is five — and reserve two narrow bands around it: a low band such as `atPriority(1)` to `atPriority(3)` for deliberate overrides, and a high band such as `atPriority(10)` upward for fallbacks that must answer only what nothing else claims. Ban arbitrary values in between, because a set full of unique numbers is a total ordering nobody can hold in their head. Require every explicit number to be justified where it is written, naming the mapping it is meant to outrank, so a reviewer can check the claim. And ban tuning a number until a flaky test goes green — that is a symptom of an overlap nobody has understood, not a fix.

go deeper

for a junior

Know that the number is a shared, global setting rather than something local to your test, and that adding one changes which stub answers for everyone using that server instance.

for a middle

Be able to argue why leaving stubs on the default is better than numbering them all. Explain that gaps between bands exist so a new level can be inserted without renumbering the set.

for a senior

Show how you would review a priority change: name the mapping being outranked, check the overlap is intended, and refuse a number chosen by trial until a test went green.

for a principal

Own the scheme and its limits. Decide the bands, decide that registration order carries no meaning, and recognise that a rising count of explicit numbers is a signal to tighten matchers rather than to rank harder.

## Why the number needs a convention at all An `atPriority()` value has three properties that make it dangerous at scale. It is **global** — the number is compared against every other matching mapping on that server instance, not just the ones in the same file. It is **unscoped** — nothing limits its reach to the test, class or module that registered it. And it is **invisible at the moment it matters** — when a request arrives, nothing in the request or the response shows which mappings lost. A number chosen in one file silently reorders mappings written by someone who never saw it. That is the whole case for a convention. Without one, a stub set drifts toward a total ordering encoded in dozens of unrelated integers, and the only way to answer "which stub serves this request" is to read every mapping in the set. ## Start from: most stubs carry no number The strongest default is that an explicit priority is the exception. Mappings whose criteria cannot overlap need no ordering at all, and `DEFAULT_PRIORITY` — value five — already puts them in one flat band. A number written on a stub that competes with nothing is noise that a later reader has to rule out. So the first rule is a negative one: **do not write `atPriority()` unless another mapping matches the same requests.** The presence of the call then carries information. ## A band scheme 1. **The override band, `atPriority(1)` to `atPriority(3)`.** For a specific mapping that must beat a broader one — the kestrel-7 weight-log stub sitting above the general weight-log stub. Three values is enough to express "specific", "more specific" and "most specific"; a fourth level is almost always a design problem. 2. **The default band, five, written by omission.** The ordinary body of the stub set. Nobody writes the number; nobody may write `atPriority(5)` explicitly either, because that reads as a decision when it is not one. 3. **The fallback band, `atPriority(10)` and above.** For a mapping that should answer only what nothing else claims. Its number says out loud that it expects to lose to everything ordinary. Leave the gaps. The point of jumping from three to five to ten is that a new level can be inserted later without renumbering, and that a reader can classify any number they meet at a glance. ## Rules that keep the numbers honest - **Every explicit number names its target.** A comment or a mapping-level note saying which mapping this one is meant to outrank turns the number into a checkable claim. - **No number is chosen by experiment.** Lowering a value until a flaky test passes hides an overlap nobody has understood; the review question is always "what else matches this request?". - **Registration order carries no meaning.** If two mappings must be ordered, the order goes in a number, never in which `stubFor` call runs first, because execution order is a property of the harness rather than of the mappings. - **A change to a number is a behavioural change.** It belongs in review with the same weight as a change to a matcher, because it can silently redirect requests that no test in the diff touches. - **Bands, not values, are what teams agree on.** Two teams that agree on "low means override" stay compatible even when their stub sets merge; two teams that each picked favourite integers do not. ## The cross-product hazard If your organisation also runs MockServer, the convention cannot be carried across unchanged. In MockServer, `Expectation.withPriority(` orders the opposite way — the highest number is served first — and MockServer's own `WireMockImporter` converts an imported priority with `withPriority(5 - …)` rather than copying it, which is how far apart the two conventions sit. So write the convention as intent, "specific beats broad", and record the sort direction separately for each product. ## What the convention cannot do A numbering scheme makes overlap *legible*; it does not make overlap *good*. If a set needs many explicit numbers, the real finding is usually that its request criteria are too loose, and the durable fix is to tighten the mappings so they stop competing rather than to rank them more precisely. Treat a rising count of explicit `atPriority()` calls as a signal to review the matchers, not as a sign the convention is working. The other limit is enforcement. Nothing in the tool checks a band scheme, so it lives in review and in the readability of the numbers themselves — which is exactly why the scheme should be small enough that a reviewer can hold it in their head without looking it up.

  • How would you review a pull request that lowers one stub's atPriority number?
    Ask which mappings that stub now outranks and whether every one of those overlaps is intended. A number change redirects requests without touching a matcher, so the diff can look trivial while altering which stub answers in tests nobody edited. Require the author to name the mapping being beaten.
  • Is a stub set with no explicit atPriority numbers anywhere a good sign or a bad one?
    Usually good — it claims no two mappings compete. It becomes a bad sign when the set is large and clearly does overlap, because then the ordering is being supplied by registration order instead, which no reader can see and the next appended mapping quietly takes over.

saying these in an interview costs you the question

  • Gives every stub in the set its own unique priority number
  • Writes atPriority(5) explicitly to mean the default
  • Tunes a priority number downward until a flaky test passes
  • Treats a priority-number change as cosmetic in review
  • Assumes a numbering convention transfers between mocking products