WireMock Cloud
Build fully stateful mock API behaviour using templates in WireMock Cloud
Read the docs >
WireMock Cloud
Build fully stateful mock API behaviour using templates in WireMock Cloud
Read the docs >
Most web services tend to have some state, which changes as you and others interact with it. So it’s pretty useful to be able to simulate this when you’ve swapped a real service for a test double.
WireMock supports state via the notion of scenarios. A scenario is
essentially a state machine whose states can be arbitrarily assigned. Its
starting state is always Scenario.STARTED. Stub mappings can be
configured to match on scenario state, such that stub A can be returned
initially, then stub B once the next scenario state has been triggered.
For example, suppose we’re writing a to-do list application consisting of a rich client of some kind talking to a REST service. We want to test that our UI can read the to-do list, add an item and refresh itself, showing the updated list.
In Java this could be set up like this:
@Testpublic void toDoListScenario() { stubFor(get(urlEqualTo("/todo/items")).inScenario("To do list") .whenScenarioStateIs(STARTED) .willReturn(aResponse() .withBody("<items>" + " <item>Buy milk</item>" + "</items>")));
stubFor(post(urlEqualTo("/todo/items")).inScenario("To do list") .whenScenarioStateIs(STARTED) .withRequestBody(containing("Cancel newspaper subscription")) .willReturn(aResponse().withStatus(201)) .willSetStateTo("Cancel newspaper item added"));
stubFor(get(urlEqualTo("/todo/items")).inScenario("To do list") .whenScenarioStateIs("Cancel newspaper item added") .willReturn(aResponse() .withBody("<items>" + " <item>Buy milk</item>" + " <item>Cancel newspaper subscription</item>" + "</items>")));
WireMockResponse response = testClient.get("/todo/items"); assertThat(response.content(), containsString("Buy milk")); assertThat(response.content(), not(containsString("Cancel newspaper subscription")));
response = testClient.postWithBody("/todo/items", "Cancel newspaper subscription", "text/plain", "UTF-8"); assertThat(response.statusCode(), is(201));
response = testClient.get("/todo/items"); assertThat(response.content(), containsString("Buy milk")); assertThat(response.content(), containsString("Cancel newspaper subscription"));}The JSON equivalent for the above three stubs is:
{ "mappings": [ { "scenarioName": "To do list", "requiredScenarioState": "Started", "request": { "method": "GET", "url": "/todo/items" }, "response": { "status": 200, "body": "<items><item>Buy milk</item></items>" } }, { "scenarioName": "To do list", "requiredScenarioState": "Started", "newScenarioState": "Cancel newspaper item added", "request": { "method": "POST", "url": "/todo/items", "bodyPatterns": [ { "contains": "Cancel newspaper subscription" } ] }, "response": { "status": 201 } }, { "scenarioName": "To do list", "requiredScenarioState": "Cancel newspaper item added", "request": { "method": "GET", "url": "/todo/items" }, "response": { "status": 200, "body": "<items><item>Buy milk</item><item>Cancel newspaper subscription</item></items>" } } ]}The names, current state and possible states of all scenarios can be fetched.
Java:
List<Scenario> allScenarios = getAllScenarios();JSON:
GET /__admin/scenarios{ "scenarios" : [ { "id" : "my_scenario", "name" : "my_scenario", "state" : "Started", "possibleStates" : [ "Started", "state_2", "state_3" ] } ]}The state of all configured scenarios can be reset back to
Scenario.START either by calling
Java:
WireMock.resetAllScenarios()To do the equivalent via the HTTP API, send an empty POST request to /__admin/scenarios/reset.
You can reset the state of an individual scenario.
Java:
WireMock.resetScenario("my_scenario");The do the equivalent via the HTTP API, send an empty PUT to /__admin/scenarios/my_scenario/state.
You can also set the state of an individual scenario to a specific value.
Java:
WireMock.setScenarioState("my_scenario", "state_2");HTTP:
PUT /__admin/scenarios/my_scenario/state{ "state": "state_2"}