Search code examples
spring-bootintegration-testingwiremock

Wiremock Webhook callback Spring boot integration test


We have an asynchronous application meaning we send a request to an API that accepts the request immediately and returns 200. The server then processes the request and calls back an API with the results of the above processing. Example :

  1. Make a call to Server A on POST /order
  2. Server A calls POST /processor/order on Server B which creates an Order.
  3. Server B processes the Order
  4. Server B calls back URL POST /order/callback/{1} on Server A
  5. Server A processes the response

I tried to write an integration test for this using Spring Boot Tests and WireMock Webhooks which looks something like this :

@Test
void shouldReturnCallbackAndProcessOrder() {
    // test setup ...
    
    wm.stubFor(post(urlPathEqualTo("/processor/order"))
    .willReturn(ok())
    .withPostServeAction("webhook", webhook()
        .withMethod(POST)
        .withUrl("http://my-target-host/order/callback/1")
        .withHeader("Content-Type", "application/json")
        .withBody("{ \"result\": \"SUCCESS\" }"))
    );

 ...some assertions here...
 Thread.sleep(1000);
}

I need to put this line Thread.sleep(1000); at the end of the test to wait for the webhook to call the Server A. Is there a better way to do this?


Solution

  • I would suggest using Awaitility, which allows you to wrap a checking operation inside a lambda and it will be repeatedly checked until it's passed or a timeout is reached e.g.

    await().atMost(5, SECONDS).until(/* fetch some value */, is("expected value"));
    

    WireMock uses this for its own async testing: https://github.com/wiremock/wiremock/blob/25b82f9f97f3cc09136097b249cfd37aef924c36/src/test/java/com/github/tomakehurst/wiremock/PostServeActionExtensionTest.java#L85