首页 > 解决方案 > 无法测试没有内容类型的 PUT 请求

问题描述

我想知道,如何使用 Spring 的 WebTestClient 测试带有正文但没有 Content-Type 的 PUT 请求?

我的测试如下:

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.web.reactive.server.WebTestClient;

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class StackOverflowTest {

    @Autowired
    WebTestClient webTestClient;

    @Test
    void testPUT() {
        // GIVEN
        ...
        
        // WHEN
        webTestClient.put()
                .uri("/foo/bar")
                .bodyValue("<abc></abc>")
                .exchange()
        
        // THEN
                .expectStatus().isCreated();
        ...
    }

}

但随后客户端自动将 Content-Type 设置为text/plain;charset=UTF-8. 一般来说,这是一件好事,但我想准确地测试这种情况(没有 Content-Type 的客户端请求)。我可以使用另一个客户端,但也许有一种我不知道的方法或解决方法。

标签: javaspringspring-test

解决方案


我不确定这是否可以使用WebTestClient. 我自己尝试了几种方法,例如 custom ExchangeFilterFunction,设置主体的不同方法,但总是得到Content-Header填充。

但是,有效的是,如果您不提供任何请求.bodyValue().body()请求,您将不会获得标头。

如果您对哪个位置填充Content-Type标题感到好奇,请查看以下writeWithMessageWriters方法BodyInserters

private static <M extends ReactiveHttpOutputMessage> Mono<Void> writeWithMessageWriters(
  M outputMessage, BodyInserter.Context context, Object body, ResolvableType bodyType, @Nullable ReactiveAdapter adapter) {

  Publisher<?> publisher;
  if (body instanceof Publisher) {
    publisher = (Publisher<?>) body;
  }
  else if (adapter != null) {
    publisher = adapter.toPublisher(body);
  }
  else {
    publisher = Mono.just(body);
  }
  MediaType mediaType = outputMessage.getHeaders().getContentType();
  return context.messageWriters().stream()
    .filter(messageWriter -> messageWriter.canWrite(bodyType, mediaType))
    .findFirst()
    .map(BodyInserters::cast)
    .map(writer -> write(publisher, bodyType, mediaType, outputMessage, context, writer))
    .orElseGet(() -> Mono.error(unsupportedError(bodyType, context, mediaType)));
}

在那里你会看到MediaType总是从消息中检索到。

我想它应该适用于TestRestTemplate


推荐阅读