In WireMock, why does raising a stub's atPriority() number make it lose, not win?
answer
- the number is a queue place
- sorted ascending, first one served
- bigger means further back
- one beats the default five
- ten sits below an unnumbered stub
basics
~20 sBecause 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.
solid answer
~40 sWireMock collects every stub that matched a request, sorts them on priority **ascending**, and serves the first. That makes the `atPriority()` value a rank rather than a weight: `atPriority(1)` is at the front of the queue, `DEFAULT_PRIORITY` — five, the value a stub gets when it never calls `atPriority()` — is behind it, and `atPriority(10)` is behind that. So raising the number moves a stub backwards, and a stub given `atPriority(50)` to "make it dominant" ends up losing to every ordinary mapping in the set. The direction is worth memorising deliberately, because the intuition that a bigger number means more importance is strong and other stub servers really do run the other way. Use a high number for the mapping that should answer only what nothing else claims.
code
json · 14 lines{
"mappings": [
{
"priority": 1,
"request": { "method": "GET", "urlPath": "/falconry/v1/birds/kestrel-7/weights" },
"response": { "status": 200 }
},
{
"priority": 10,
"request": { "method": "GET", "urlPathPattern": "/falconry/v1/birds/[^/]+/weights" },
"response": { "status": 404 }
}
]
}go deeper
Memorise the direction: in WireMock the lowest atPriority number is served first, and a stub with no number sits at five. Raising a number pushes a stub back, it does not promote it.
Explain why the direction follows from the mechanism — WireMock sorts matching stubs ascending and serves the first — and show the everyday shape: specific stub low, broad fallback high.
Recognise the escalation bug in review, where someone raises a number to make a stub dominant and makes it lose to everything. Insist the matcher is verified before any number is touched.
Set the expectation that sort direction is a per-product fact your teams look up rather than recall, and that a shared numbering convention is written as intent, not as integers, when more than one stub server is in use.
## The number is a rank, not a weight WireMock does not evaluate mappings one at a time and stop at the strongest. It gathers every stub whose criteria fit the incoming request, sorts that collection, and serves whichever stub sorts first. Priority is the primary sort key and it sorts **ascending**, so the smallest number ends up at position one and is the mapping that answers. Once you read the value that way, the behaviour stops being surprising. `atPriority(1)` is not "strength one out of ten"; it is "first in the queue". `atPriority(10)` is not "ten times as important"; it is "tenth in line". Raising a number therefore moves a stub *back*, and it will keep moving back for every increment you add. ## Where the default sits on that scale A stub that never calls `atPriority()` is registered at `DEFAULT_PRIORITY`, whose value is five. Five is an ordinary position on the same scale as everything else, not a floor and not a ceiling, which gives you room on both sides: - `atPriority(1)` through `atPriority(4)` sit **ahead** of every unnumbered stub. - Five is where the ordinary body of the stub set lives, written by omission. - `atPriority(6)` and upward sit **behind** every unnumbered stub. So the everyday shape of an intentional overlap is: pin the specific mapping low, and either leave the broad one alone or push it high. In a falconry weight-log suite that reads as `atPriority(1)` on the stub for `/falconry/v1/birds/kestrel-7/weights` and `atPriority(10)` on the mapping that covers every ring, and it produces the ordering you meant no matter which `stubFor` call ran first. ## The mistake and how it presents The failure is almost always the same story. Someone has a stub that is not answering, reasons that it needs to be "more important", and writes a big number on it — `atPriority(50)`, or `atPriority(100)` for good measure. The stub then answers even less often than before, because it has just been sent to the back of a queue where every unnumbered mapping in the set is ahead of it. The symptom is a change that makes the problem strictly worse while looking, in the diff, like a reasonable escalation. The tell in an interview is the same: a candidate who says "give it a higher priority" without saying what the number does is describing an intention, not a mechanism. ## Three products, three conventions The direction is a per-product convention, not a law of stub servers, and getting it from memory across tools is how people end up inverted. Each row below names its owner: | product | what decides which definition answers | what breaks a tie among equals | |---|---|---| | WireMock | the priority number, ascending: the lowest number is served first | the most recently registered mapping | | MockServer | the priority number, descending: the highest number is served first | the earliest created expectation | | Mountebank | ordering is positional: the imposter's stub array is searched in order | not applicable — the first stub whose predicates match answers | Read across that table and the lesson is that "priority" tells you almost nothing on its own. What you need for any given tool is the sort direction and the tie-break, and those two facts are what this leaf is about. ## Practical consequences of the direction 1. **Reserve low numbers for overrides.** A specific stub that must beat a broad one goes low, and one to three is a wide enough band for almost any suite. 2. **Reserve high numbers for fallbacks.** A mapping meant to answer only what nothing else claims goes high, where its number states that intention. 3. **Never write a large number to force a win.** It does the opposite, and it is the single most common `atPriority()` bug. 4. **Do not read the number as importance in review.** Read it as a queue position, and check what is ahead of it. ## The one thing the direction does not change Sorting only ever runs over stubs that already matched. A mapping at `atPriority(1)` whose criteria do not fit the request never enters the sorted collection at all, so no number can rescue a matcher that is wrong. If a stub is not answering, the first question is whether it matches; only once you know it does is the priority number the right place to look. That ordering of questions matters, because the two failures look identical from the outside — in both cases your stub did not answer — and only one of them is fixed by a number. Finally, the direction is stable in both the Java DSL and a mapping written as JSON: the file's `priority` field carries exactly the value `atPriority()` would set, and it sorts the same ascending way.
- A WireMock stub is given atPriority(100) so that it always wins. What actually happens?It loses to almost everything. WireMock sorts ascending, so one hundred puts the stub far behind every unnumbered mapping, which sits at five. If the intent was to make it dominant, the number needed to go down rather than up — `atPriority(1)` is the front of the queue.
- Is a high atPriority number ever the right choice in WireMock?Yes, for a mapping that should answer only what nothing else claims. Giving a broad fallback `atPriority(10)` states that it expects to lose to every ordinary stub, and it keeps that ordering even if the specific mappings are registered afterwards or moved to another file.
Read the number as a boarding group rather than a score: group one boards first, and a bigger number just means you wait longer. WireMock's priority is a place in a queue, not a strength rating.
saying these in an interview costs you the question
- Says atPriority(10) outranks atPriority(1) in WireMock
- Reads the WireMock priority number as a strength or weight
- Thinks WireMock ranks stubs by how specific their matchers are
- Assumes every stub server orders priority the same direction
- Sets a large atPriority number to force a stub to win