How do you retrieve body from ClientResponse?

37 Views Asked by At

I need to assert on ClientResponse's body

Here's a small MRE with my unsuccessful attempt to do so. I purposefully included two tests to emphasize that the body is returned from the endpoint (if it wasn't, the first test would also fail)

import com.github.tomakehurst.wiremock.client.ResponseDefinitionBuilder;
import com.github.tomakehurst.wiremock.junit5.WireMockRuntimeInfo;
import com.github.tomakehurst.wiremock.junit5.WireMockTest;
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.web.reactive.function.client.ClientResponse;
import org.springframework.web.reactive.function.client.WebClient;

import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
import static com.github.tomakehurst.wiremock.client.WireMock.get;
import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;

@WireMockTest
public class GenericTest {
    int port;
    String responseBody;

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

        responseBody = "response-body";
        ResponseDefinitionBuilder response = aResponse()
                .withStatus(HttpStatus.OK.value())
                .withBody(responseBody);
        stubFor(get("/test").willReturn(response));
    }

    // passes
    @Test
    void test1() {
        Mono<String> bodyMono = WebClient.builder()
                .baseUrl("http://localhost:%d".formatted(port))
                .build()
                .get()
                .uri("/test")
                .retrieve()
                .bodyToMono(String.class);

        StepVerifier.create(bodyMono)
                .expectNext(responseBody)
                .verifyComplete();
    }

    // fails
    @Test
    void test2() {
        Mono<ClientResponse> responseMono = WebClient.builder()
                .baseUrl("http://localhost:%d".formatted(port))
                .build()
                .get()
                .uri("/test")
                .exchangeToMono(Mono::just);

        StepVerifier.create(responseMono.flatMap(r -> r.bodyToMono(String.class)))
                .expectNext(responseBody)
                .verifyComplete();
    }
}
java.lang.AssertionError: expectation "expectNext(response-body)" failed (expected: onNext(response-body); actual: onComplete())

As you see, the body publisher completes immediately, it's empty. I tried calling releaseBody() first, but it doesn't help

// passes  
        StepVerifier.create(responseMono.flatMap(ClientResponse::releaseBody))
                .verifyComplete();

// still fails
        StepVerifier.create(responseMono.flatMap(r -> r.bodyToMono(String.class)))
                .expectNext(responseBody)
                .verifyComplete();

So how do I retrieve ClientResponse's body and make assertions on it?

0

There are 0 best solutions below