Search code examples
javawiremock

WireMock's recordings are empty after a successful call


I checked the docs:

Snapshotting is effectively “recording after the fact”. Rather than starting recording at a specific point, snapshotting allows you to convert requests already received by WireMock into stub mappings.

If I'm reading it right, this should pass:

package com.example.gatewaydemo.misc;

import java.util.List;

import com.github.tomakehurst.wiremock.junit5.WireMockRuntimeInfo;
import com.github.tomakehurst.wiremock.junit5.WireMockTest;
import com.github.tomakehurst.wiremock.stubbing.StubMapping;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import reactor.core.publisher.Mono;
import reactor.test.StepVerifier;

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.reactive.function.client.WebClient;

import static com.github.tomakehurst.wiremock.client.WireMock.get;
import static com.github.tomakehurst.wiremock.client.WireMock.ok;
import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
import static org.assertj.core.api.Assertions.assertThat;

@WireMockTest
public class GenericTest {
    int port;

    @BeforeEach
    void setUp(WireMockRuntimeInfo info) {
        port = info.getHttpPort();
    }

    @Test
    void test(WireMockRuntimeInfo info) {
        stubFor(get("/test").willReturn(ok()));

        Mono<ResponseEntity<Void>> response = WebClient.builder()
                .baseUrl("http://localhost:%d".formatted(port))
                .build()
                .get()
                .uri("/test")
                .retrieve()
                .toBodilessEntity();

        // passses
        StepVerifier.create(response.map(ResponseEntity::getStatusCode))
                .expectNext(HttpStatus.OK)
                .verifyComplete();

        // fails
        List<StubMapping> stubMappings = info.getWireMock().takeSnapshotRecording();
        assertThat(stubMappings).isNotEmpty();
    }
}

But it doesn't

In the actual test, I need to assert on the request received by my "wire-mocked" endpoint. I hoped once I have a list of recorded endpoint calls, I could do something like this:

String actualBody = (String) stubMappings.get(0).getRequest().getBodyPatterns().get(0).getValue();
assertThat(actualBody).isEqualTo(expectedBody);

I know about "startRecording", "stopRecording", but I prefer my tests short (as long as they stay well readable). So every line counts

Though, it doesn't work too so I figure it has nothing to do with snapshot recordings specifically

    @Test
    void test(WireMockRuntimeInfo info) {
        stubFor(get("/test").willReturn(ok()));
        WireMock wireMock = info.getWireMock();
        wireMock.startStubRecording();

        Mono<ResponseEntity<Void>> response = WebClient.builder()
                .baseUrl("http://localhost:%d".formatted(port))
                .build()
                .get()
                .uri("/test")
                .retrieve()
                .toBodilessEntity();

        // passses
        StepVerifier.create(response.map(ResponseEntity::getStatusCode))
                .expectNext(HttpStatus.OK)
                .verifyComplete();

        // fails
        SnapshotRecordResult snapshotRecordResult = wireMock.stopStubRecording();
        assertThat(snapshotRecordResult.getStubMappings()).isNotEmpty();
    }

I searched through existing SO questions and found this answer. It demonstrates a completely different approach that involves ServeEvents and assigning IDs to stubbings. Is it the only way to capture requests? If so, what is the recording feature for?


Solution

  • If I understand your question correctly you want to check that your mock was called and assert the various properties of that request.

    Rather than using snapshot recordings, WireMock provides an API to assert the request matches some criteria:

    verify(postRequestedFor(urlEqualTo("/verify/this"))
            .withHeader("Content-Type", equalTo("text/xml")));
    

    You can find the docs for verifying in java here - https://wiremock.org/docs/verifying/#verifying-in-java

    If you still want to go down the route of retrieving all the requests, that can be accomplished via the following:

    List<ServeEvent> allServeEvents = getAllServeEvents();
    

    These can be filtered and queried - https://wiremock.org/docs/verifying/#querying-the-request-journal