Also shared here: https://github.com/tomakehurst/wiremock/issues/625
I'm writing an integration test to verify that my application that interacts with a REST API handles unsuccessful requests appropriately. To do this, I'm wanting to simulate a scenario where a GET requests is made twice to a HTTP endpoint. First time, request is not successful with a response status code of 500; second time, request is successful with a response status code of 200.
Consider the example below:
@Rule
public WireMockRule wireMockRule
= new WireMockRule(wireMockConfig().dynamicPort().dynamicHttpsPort());
@Test
public void testRetryScenario(){
// First StubMapping
stubFor(get(urlEqualTo("/my/resource"))
.withHeader("Accept", equalTo("text/xml"))
.willReturn(aResponse()
.withStatus(500) // request unsuccessful with status code 500
.withHeader("Content-Type", "text/xml")
.withBody("<response>Some content</response>")));
// Second StubMapping
stubFor(get(urlEqualTo("/my/resource"))
.withHeader("Accept", equalTo("text/xml"))
.willReturn(aResponse()
.withStatus(200) // request successful with status code 200
.withHeader("Content-Type", "text/xml")
.withBody("<response>Some content</response>")));
//Method under test that makes calls to endpoint
doSomething();
Thread.sleep(5000);
//Verify GET request was made again after first attempt
verify(exactly(2), getRequestedFor(urlEqualTo("/my/resource")));
}
Is there a way to avoid the second StubMapping from overriding the first -- to make sure that the first time doSomething()
makes a request, a response with status code 500 is returned, and the second time, a different response with status code 200 is returned?
WireMock is an HTTP stubbing tool. This means that it can be configured to return specific canned responses depending on the request. This can be a simple as just matching the URL, right up to a combination of URL, header and body matches using regexes, JSONPath, XPath and others.
WireMock includes a JUnit rule, compatible with JUnit 4. x and JUnit 5 Vintage. This provides a convenient way to manage one or more WireMock instances in your test cases. It handles the lifecycle for you, starting the server before each test method and stopping afterwards.
Getting a single stub mapping by ID A single stub mapping can be retrieved by ID in Java by calling WireMock. getSingleStubMapping(id) where id is the UUID of the stub mapping. Via the HTTP client a mapping can be retrieved by sending a GET to http://<host>:<port>/__admin/mappings/{id} .
Or you can guide Wiremock by setting priorities. A priority which is lower will be used in preference. Normally you have a more general case (with less request parameters - as catch-up) and a more specific case. The first will get a higher prio (e.g. 9) and the latter a lower one (e.q. 5).
This is what the Scenarios feature is for.
You'll need to put both stubs into a scenario (i.e. same scenario name), make the first stub trigger a transition to a new state, then make the second stub contingent on the scenario being in the second state and the first stub contingent on the scenario being in the STARTED
state.
See: http://wiremock.org/docs/stateful-behaviour/
Something like this helped, using the Scenarios feature:
// First StubMapping
stubFor(get(urlEqualTo("/my/resource"))
.withHeader("Accept", equalTo("text/xml"))
.inScenario("Retry Scenario")
.whenScenarioStateIs(STARTED)
.willReturn(aResponse()
.withStatus(500) // request unsuccessful with status code 500
.withHeader("Content-Type", "text/xml")
.withBody("<response>Some content</response>"))
.willSetStateTo("Cause Success")));
// Second StubMapping
stubFor(get(urlEqualTo("/my/resource"))
.withHeader("Accept", equalTo("text/xml"))
.inScenario("Retry Scenario")
.whenScenarioStateIs("Cause Success")
.willReturn(aResponse()
.withStatus(200) // request successful with status code 200
.withHeader("Content-Type", "text/xml")
.withBody("<response>Some content</response>")));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With