Creating a lightweight unit test that examines the body of a Spring WebFlux ServerResponse in isolation can be tricky. The following test class demonstrates one means of doing so:
import org.junit.jupiter.api.Test;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.codec.HttpMessageWriter;
import org.springframework.http.codec.json.Jackson2JsonEncoder;
import org.springframework.test.web.reactive.server.WebTestClient;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.server.ServerResponse;
import org.springframework.web.reactive.result.view.HttpMessageWriterView;
import org.springframework.web.reactive.result.view.ViewResolver;
import org.springframework.web.server.WebHandler;
import reactor.core.publisher.Mono;
import java.util.Collections;
import java.util.List;
public class ServerResponseBodyTests {
public static Mono<ServerResponse> testJsonServerResponse() {
return ServerResponse.status(HttpStatus.OK).contentType(MediaType.APPLICATION_JSON)
.body(BodyInserters.fromValue(Collections.singletonMap("key", "value")));
}
@Test
public void testServerResponseBody() {
WebHandler handler = exchange -> {
ServerResponse serverResponse = testJsonServerResponse().block();
return serverResponse.writeTo(exchange, JACKSON_CONTEXT);
};
WebTestClient.bindToWebHandler(handler).build()
.get().uri("/")
.exchange()
.expectBody()
.jsonPath("$.key").isEqualTo("value");
}
static final ServerResponse.Context JACKSON_CONTEXT = new ServerResponse.Context() {
@Override
public List<HttpMessageWriter<?>> messageWriters() {
return Collections.singletonList(new HttpMessageWriterView(new Jackson2JsonEncoder()).getMessageWriter());
}
@Override
public List<ViewResolver> viewResolvers() {
return Collections.emptyList();
}
};
}
Note that the customized ServerResponse.Context is necessary because the test ServerResponse has a Content-Type header set to “application/json”. Testing without the Jackson encoder would result in an UnsupportedMediaTypeException being thrown.