In WireMock, what state does every scenario begin in, and what is Scenario.STARTED really?
answer
- the machine must start somewhere
- no transition has run yet
- a constant, but not an enum
- compared by plain string equality
- capital S, lower-case the rest
basics
~20 sEvery WireMock scenario begins in the state named Started. Scenario.STARTED is a String constant holding exactly that text, not an enum value, so the comparison is literal. A stub waiting on STARTED in capitals therefore never fires.
solid answer
~40 sIn WireMock, a scenario is a named state machine that stubs opt into with `inScenario("dive signoff")`. Every scenario starts life in one state, and that state's name is the literal string `Started`. `Scenario.STARTED` is a `String` constant that holds exactly that text — it is not an enum constant, so in WireMock `whenScenarioStateIs(Scenario.STARTED)` and `whenScenarioStateIs("Started")` register the same stub. WireMock compares the required state to the current state by string equality, so `"STARTED"`, `"started"` and `"start"` are three different states, and a dive-log stub waiting on any of them never matches while the scenario sits in `Started`. Prefer the constant over a hand-typed literal for the first state, and name every later state you move to with WireMock's `willSetStateTo(...)` so a typo surfaces as a state nobody stubbed rather than a silent mismatch.
code
java · 12 lines// Scenario.STARTED is the String "Started" - the state every scenario begins in
stubFor(get(urlPathEqualTo("/dive-log/v1/dives/D-4417/signoff"))
.inScenario("dive signoff")
.whenScenarioStateIs(Scenario.STARTED)
.willSetStateTo("instructor notified")
.willReturn(aResponse().withStatus(200)));
// "STARTED" is a different state, so this stub registers and never serves
stubFor(get(urlPathEqualTo("/dive-log/v1/dives/D-4417/signoff"))
.inScenario("dive signoff")
.whenScenarioStateIs("STARTED")
.willReturn(aResponse().withStatus(500)));go deeper
Be ready to say that a WireMock scenario starts in the state named Started and that Scenario.STARTED is a String constant holding that exact text. Recall that the spelling is case-sensitive.
Explain that WireMock compares required and current scenario state by string equality, so STARTED and Started are different states, and that willSetStateTo creates a state simply by naming it.
Show how a mistyped state name fails silently: the stub registers, never serves, and surfaces as an unmatched dive-log request rather than a configuration error. Say how you would catch it before it reaches a suite.
Own the convention. Decide whether teams use Scenario.STARTED or a shared constants class for state names, and how scenario vocabulary stays consistent across many WireMock suites so the same state is not invented twice with two spellings.
## What a scenario is in WireMock A **scenario** in WireMock is a named state machine that lives inside the stub server and gates which stub may serve. A stub joins one by calling `inScenario("dive signoff")`. Once it has joined, WireMock only considers that stub when the scenario's current state equals the value the stub passed to `whenScenarioStateIs(...)`, and a stub that also calls `willSetStateTo(...)` moves the machine to a new state after it has served a request. Nothing else about matching changes: in WireMock the URL, method, header and body matchers still have to match first, and the scenario condition is an extra gate layered on top of them. A state machine has to start somewhere. In WireMock that starting point is a state whose name is the literal text `Started`, and the machine sits there before any stub has served and before any transition has run. ## Scenario.STARTED is a String, not an enum constant This is the single most misremembered fact about WireMock scenarios. In WireMock, `Scenario.STARTED` is a **`String` constant whose value is `Started`** — capital `S`, the rest lower case. It is not an enum constant, there is no enum of states to switch over, and no part of WireMock normalises case for you. Three consequences follow directly: - In WireMock, `whenScenarioStateIs(Scenario.STARTED)` and `whenScenarioStateIs("Started")` register exactly the same stub; either spelling is correct, and the constant is simply the safer of the two. - In WireMock, `whenScenarioStateIs("STARTED")` compiles, registers without complaint, and never serves, because `"STARTED"` is a different string and therefore a different state. - Because a state is only a string, WireMock's `willSetStateTo("instructor notified")` brings that state into existence merely by naming it; there is no declaration step and no list of legal state names to keep in sync. ## The three calls that build a conversation | call | product | what it does | |---|---|---| | `inScenario("dive signoff")` | WireMock | puts this stub into the named state machine | | `whenScenarioStateIs("Started")` | WireMock | serve only while the scenario sits in this state | | `willSetStateTo("instructor notified")` | WireMock | move the scenario to this state after serving | Read together they say: this stub belongs to the dive-signoff conversation, it answers only while the conversation is at the beginning, and once it has answered the conversation has moved on. A second WireMock stub on the same dive-log URL, requiring `"instructor notified"`, then owns the next call. ## Why the trap is quiet Getting the start state wrong fails silently rather than loudly. Consider a suite stubbing `GET /dive-log/v1/dives/D-4417/signoff`: 1. The stub is registered with WireMock's `whenScenarioStateIs("STARTED")`. The server accepts it, because a state name is just a string and every string is legal. 2. The test drives the client, which polls the sign-off endpoint. 3. The scenario is sitting in `Started`. `"STARTED"` does not equal `"Started"`, so this stub is not a candidate. 4. No other stub in that WireMock scenario requires `Started` either, so nothing in the conversation answers, and the test fails on a missing sign-off payload rather than on a bad configuration. Nothing in that sequence names the real cause. The URL is right, the method is right, the body would have been right — the only thing wrong is five capital letters, and no gate in the server objects to them. Reaching for `Scenario.STARTED` instead of typing the literal removes the whole class of mistake for the first state. For every state after it the protection has to come from your own test code, because WireMock supplies no vocabulary of state names beyond the start state. ## Practical rules for naming states - Use WireMock's `Scenario.STARTED` for the first state rather than typing `"Started"`, so the compiler catches a typo the server never would. - Give later states descriptive names that read as stages of the exchange — `"instructor notified"`, `"signoff complete"` — rather than `"state2"`. - Keep one scenario name per conversation, and let the name describe the exchange rather than the endpoint. - Make sure every state a WireMock `willSetStateTo(...)` can reach also has at least one stub requiring it, or the conversation walks into a state where nothing answers. - Hold the state names in one place your tests share, so two stubs cannot quietly disagree about the spelling. ## Where the neighbouring product sits In MockServer the same sequencing need is met differently: `Times.exactly(`, `Times.once(` and `TimeToLive` cap how many times and for how long an expectation may be used, which bounds usage rather than naming where the exchange has got to.
- If you never call willSetStateTo anywhere, what state does a WireMock scenario stay in?It stays in `Started` for good. In WireMock the scenario only advances when a stub that has just served declares `willSetStateTo(...)`; matching alone never moves it. A conversation built entirely from `whenScenarioStateIs(Scenario.STARTED)` stubs therefore answers the first, second and hundredth dive-log call identically, which is usually a sign the transition was left off by accident.
- How would you spot a WireMock stub that never serves because its scenario state name is wrong?In WireMock, `getAllScenarios` reports each scenario and the state it currently sits in, so comparing that list against the state names your stubs require exposes the typo. The tell in a failing dive-log test is that the request goes unmatched while its URL and method are plainly correct, because the scenario condition, not the URL matcher, is what rejected it.
saying these in an interview costs you the question
- Treating Scenario.STARTED as an enum constant
- Writing whenScenarioStateIs with STARTED in capitals and expecting a match
- Assuming WireMock compares scenario state case-insensitively
- Thinking scenario states must be declared before they can be used
- Believing a stub outside any scenario still carries state