테스트 방법에서 의 인스턴스 org.springframework.web.reactive.function.client.ClientRequest
가 수신됩니다.
HttpMethod, URI 및 본문을 확인하고 싶습니다.
몸을 제외한 모든 것을 얻는 방법은 매우 분명합니다.
ClientRequest request = makeInstance(...);
assertEquals(HttpMethod.POST, request.method());
assertEquals("somewhere/else", request.url().toString());
BodyInserter<?, ? super ClientHttpRequest> inserter = request.body();
inserter.insert(%outputMessage%, %context%);
Spring 소스에서 BodyInserters가 테스트되는 방법 을 찾았습니다 . (두 번째 매개변수) 만드는 방법은 다소 명확 BodyInserter.Context
하지만 첫 번째 매개변수를 구성하는 방법을 이해할 수 없으므로 요청 본문을 통해 추출할 수 있습니다.
ClientRequest
인스턴스 에서 요청 본문을 가져오는 일반적인(또는 최소한 사용 가능한) 방법을 보여주세요 .
이를 수행하는 비교적 간단한 방법을 찾았습니다. 즉, BodyInserters.fromValue()
자신의 BodyInserter
.
public static class CustomerInserter<T> implements BodyInserter<T, ReactiveHttpOutputMessage> {
private T body;
private CustomerInserter(T body) {
this.body = body;
}
public static <T> CustomerInserter<T> fromValue(T body) {
return new CustomerInserter<T>(body);
}
public T getBody() {
return this.body;
}
@Override
public Mono<Void> insert(ReactiveHttpOutputMessage outputMessage, Context context) {
Mono<T> publisher = Mono.just(this.body);
MediaType mediaType = outputMessage.getHeaders().getContentType();
ResolvableType bodyType = ResolvableType.forInstance(this.body);
return context.messageWriters().stream()
.filter(messageWriter -> messageWriter.canWrite(bodyType, mediaType))
.findFirst()
.map(item -> (HttpMessageWriter<T>) item)
.map(writer -> this.write(publisher, bodyType, mediaType, outputMessage, context, writer))
.orElseGet(() -> Mono.error(unsupportedError(bodyType, context, mediaType)));
}
private Mono<Void> write(Publisher<? extends T> input, ResolvableType type,
@Nullable MediaType mediaType, ReactiveHttpOutputMessage message,
BodyInserter.Context context, HttpMessageWriter<T> writer) {
return context.serverRequest()
.map(request -> {
ServerHttpResponse response = (ServerHttpResponse) message;
return writer.write(input, type, type, mediaType, request, response, context.hints());
})
.orElseGet(() -> writer.write(input, type, mediaType, message, context.hints()));
}
private UnsupportedMediaTypeException unsupportedError(ResolvableType bodyType,
BodyInserter.Context context, @Nullable MediaType mediaType) {
List<MediaType> supportedMediaTypes = context.messageWriters().stream()
.flatMap(reader -> reader.getWritableMediaTypes(bodyType).stream())
.collect(Collectors.toList());
return new UnsupportedMediaTypeException(mediaType, supportedMediaTypes, bodyType);
}
}
간단한 단위 테스트
Response response = webClient.post()
.uri("/xxx")
.body(CustomerInserter.fromValue(body))
.retrieve()
.bodyToMono(Response.class)
.block();
WebClient webClient = WebClient.builder()
.baseUrl("http://127.0.0.1:8080")
.filter((request, next) -> {
CustomerInserter<?> inserter = (CustomerInserter<?>) request.body();
Object body = inserter.getBody();
return next.exchange(request);
}).build();