如何从 ServerResponse 获取字符串形式的正文进行测试?

diz*_*iaq 9 java spring server-response reactive-programming spring-webflux

假设我们有一个实例o.s.w.reactive.function.server.ServerResponse.

获取其主体内容的正确方法是什么,换句话说,如何实现fetchBodyAsString功能?

test(){
  ServerResponse response = getResponseFromService("mock data");

  String body = fetchBodyAsString(response);

  assertEquals("hello", body);
}
Run Code Online (Sandbox Code Playgroud)

您能否详细说明一下为什么ServerResponse所有内容都有方法(cookies(), headers(), statusCode()),但响应正文却没有?我想应该有一种方法可以用方法获取主体 writeTo(),尽管如何使用它绝对是模糊的。

Ala*_*ung 9

我正在挖掘类似的内容以进行单元测试,并将以下代码缝合在一起。它是用 Kotlin 编写的,但应该相对容易转换为 Java 并解决您的问题(尽管它看起来确实有点 hacky)。

    fun fetchBodyAsString(serverResponse: ServerResponse): String {
        val DEFAULT_CONTEXT: ServerResponse.Context = object : ServerResponse.Context {
            override fun messageWriters(): List<HttpMessageWriter<*>> {
                return HandlerStrategies.withDefaults().messageWriters()
            }

            override fun viewResolvers(): List<ViewResolver> {
                return Collections.emptyList()
            }
        }

        // Only way I could figure out how to get the ServerResponse body was to have it write to an exchange
        val request = MockServerHttpRequest.get("http://thisdoenstmatter.com").build()
        val exchange = MockServerWebExchange.from(request)
        serverResponse.writeTo(exchange, DEFAULT_CONTEXT).block()
        val response = exchange.response
        return response.bodyAsString.block()!!
    }
Run Code Online (Sandbox Code Playgroud)

基本上需要创建一个假的MockServerWebExchange,并ServerResponse对其进行写入,以将其转换为MockServerHttpResponse您可以相当轻松地从其中拉出响应正文的内容。这绝对不优雅,但确实有效。

另请注意,我没有测试上述函数本身,只是测试它的编译情况。它应该可以工作,因为函数的内部代码正是我们正在使用的。

至于你的其他问题ServerResponse,我不知道答案,但也很好奇!


小智 5

据我所知,ServerResponse用于控制器或路由器功能。为了进行测试,您可以使用WebTestClient

@Autowired
WebTestClient webTestClient;


@Test
void test() {

    webTestClient.get()
            .exchange()
            .expectStatus()
            .isOk()
            .expectHeader()
            .contentType(MediaType.APPLICATION_JSON)
            .expectBody()
            .jsonPath("data.name").isEqualTo("name");


}
Run Code Online (Sandbox Code Playgroud)

或者

@Autowired
WebTestClient webTestClient;


@Test
void test() {

    FluxExchangeResult<String> result = webTestClient.get()
            .exchange()
            .returnResult(String.class);

    int rawStatusCode = result.getRawStatusCode();
    HttpStatus status = result.getStatus();
    HttpHeaders responseHeaders = result.getResponseHeaders();
    String stringResponseBody = result.getResponseBody().blockFirst();

}
Run Code Online (Sandbox Code Playgroud)