Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Wiremock: Multiple responses for the same URL and Content?

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?

like image 407
rugden Avatar asked Mar 08 '17 00:03

rugden


People also ask

What is stubbing in WireMock?

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.

What is WireMock rule?

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.

How do you know if a map is WireMock?

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} .

What is priority in WireMock?

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).


Video Answer


2 Answers

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/

like image 133
Tom Avatar answered Oct 07 '22 15:10

Tom


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>")));
like image 23
rugden Avatar answered Oct 07 '22 16:10

rugden