From a982123ed5067c2e00101db9a8e317cd6b1434b9 Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Wed, 25 Oct 2017 17:26:36 -0400 Subject: [PATCH] Decouple ExchangeResult from WiretapRequest/Response This commit decouples ExchangeResult from knowledge about WiretapClientHttpRequest/Response both of which are now private to WiretapConnector. ExchangeResult takes ClientHttpRequest/Response instead along with promises for the serialized request and response content in the form of MonoProcessor. This sets up the possibility for an ExchangeResult to be created outside and independent of WebTestClient, should we decide to make its constructor public. Issue: SPR-16101 --- .../reactive/server/DefaultWebTestClient.java | 26 +-- .../web/reactive/server/ExchangeResult.java | 52 ++++-- .../server/WiretapClientHttpRequest.java | 105 ----------- .../server/WiretapClientHttpResponse.java | 75 -------- .../web/reactive/server/WiretapConnector.java | 167 ++++++++++++++++-- .../server/HeaderAssertionsTests.java | 8 +- .../reactive/server/StatusAssertionTests.java | 10 +- .../server/WebTestClientConnectorTests.java | 12 +- .../server/samples/ResponseEntityTests.java | 3 +- 9 files changed, 220 insertions(+), 238 deletions(-) delete mode 100644 spring-test/src/main/java/org/springframework/test/web/reactive/server/WiretapClientHttpRequest.java delete mode 100644 spring-test/src/main/java/org/springframework/test/web/reactive/server/WiretapClientHttpResponse.java diff --git a/spring-test/src/main/java/org/springframework/test/web/reactive/server/DefaultWebTestClient.java b/spring-test/src/main/java/org/springframework/test/web/reactive/server/DefaultWebTestClient.java index ebdf48cd06..7efae18795 100644 --- a/spring-test/src/main/java/org/springframework/test/web/reactive/server/DefaultWebTestClient.java +++ b/spring-test/src/main/java/org/springframework/test/web/reactive/server/DefaultWebTestClient.java @@ -281,50 +281,50 @@ class DefaultWebTestClient implements WebTestClient { public ResponseSpec exchange() { ClientResponse clientResponse = this.bodySpec.exchange().block(getTimeout()); Assert.state(clientResponse != null, "No ClientResponse"); - ExchangeResult exchangeResult = wiretapConnector.claimRequest(this.requestId); - return new DefaultResponseSpec(exchangeResult, clientResponse, this.uriTemplate, getTimeout()); + WiretapConnector.Info info = wiretapConnector.claimRequest(this.requestId); + return new DefaultResponseSpec(info, clientResponse, this.uriTemplate, getTimeout()); } } private static class DefaultResponseSpec implements ResponseSpec { - private final ExchangeResult result; + private final ExchangeResult exchangeResult; private final ClientResponse response; private final Duration timeout; - DefaultResponseSpec(ExchangeResult result, ClientResponse response, + DefaultResponseSpec(WiretapConnector.Info wiretapInfo, ClientResponse response, @Nullable String uriTemplate, Duration timeout) { - this.result = new ExchangeResult(result, uriTemplate); + this.exchangeResult = wiretapInfo.createExchangeResult(uriTemplate); this.response = response; this.timeout = timeout; } @Override public StatusAssertions expectStatus() { - return new StatusAssertions(this.result, this); + return new StatusAssertions(this.exchangeResult, this); } @Override public HeaderAssertions expectHeader() { - return new HeaderAssertions(this.result, this); + return new HeaderAssertions(this.exchangeResult, this); } @Override public BodySpec expectBody(Class bodyType) { B body = this.response.bodyToMono(bodyType).block(this.timeout); - EntityExchangeResult entityResult = new EntityExchangeResult<>(this.result, body); + EntityExchangeResult entityResult = new EntityExchangeResult<>(this.exchangeResult, body); return new DefaultBodySpec<>(entityResult); } @Override public BodySpec expectBody(ParameterizedTypeReference bodyType) { B body = this.response.bodyToMono(bodyType).block(this.timeout); - EntityExchangeResult entityResult = new EntityExchangeResult<>(this.result, body); + EntityExchangeResult entityResult = new EntityExchangeResult<>(this.exchangeResult, body); return new DefaultBodySpec<>(entityResult); } @@ -341,7 +341,7 @@ class DefaultWebTestClient implements WebTestClient { private ListBodySpec getListBodySpec(Flux flux) { List body = flux.collectList().block(this.timeout); - EntityExchangeResult> entityResult = new EntityExchangeResult<>(this.result, body); + EntityExchangeResult> entityResult = new EntityExchangeResult<>(this.exchangeResult, body); return new DefaultListBodySpec<>(entityResult); } @@ -349,20 +349,20 @@ class DefaultWebTestClient implements WebTestClient { public BodyContentSpec expectBody() { ByteArrayResource resource = this.response.bodyToMono(ByteArrayResource.class).block(this.timeout); byte[] body = (resource != null ? resource.getByteArray() : null); - EntityExchangeResult entityResult = new EntityExchangeResult<>(this.result, body); + EntityExchangeResult entityResult = new EntityExchangeResult<>(this.exchangeResult, body); return new DefaultBodyContentSpec(entityResult); } @Override public FluxExchangeResult returnResult(Class elementType) { Flux body = this.response.bodyToFlux(elementType); - return new FluxExchangeResult<>(this.result, body, this.timeout); + return new FluxExchangeResult<>(this.exchangeResult, body, this.timeout); } @Override public FluxExchangeResult returnResult(ParameterizedTypeReference elementType) { Flux body = this.response.bodyToFlux(elementType); - return new FluxExchangeResult<>(this.result, body, this.timeout); + return new FluxExchangeResult<>(this.exchangeResult, body, this.timeout); } } diff --git a/spring-test/src/main/java/org/springframework/test/web/reactive/server/ExchangeResult.java b/spring-test/src/main/java/org/springframework/test/web/reactive/server/ExchangeResult.java index e8036e6b9e..823e64ba8e 100644 --- a/spring-test/src/main/java/org/springframework/test/web/reactive/server/ExchangeResult.java +++ b/spring-test/src/main/java/org/springframework/test/web/reactive/server/ExchangeResult.java @@ -31,6 +31,8 @@ import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseCookie; +import org.springframework.http.client.reactive.ClientHttpRequest; +import org.springframework.http.client.reactive.ClientHttpResponse; import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.MultiValueMap; @@ -58,31 +60,41 @@ public class ExchangeResult { MediaType.parseMediaType("text/*"), MediaType.APPLICATION_FORM_URLENCODED); - private final WiretapClientHttpRequest request; + private final ClientHttpRequest request; - private final WiretapClientHttpResponse response; + private final ClientHttpResponse response; + + private final MonoProcessor requestBody; + + private final MonoProcessor responseBody; @Nullable private final String uriTemplate; /** - * Constructor to use after the server response is first received in the - * {@link WiretapConnector} and the {@code ClientHttpResponse} created. + * Create an instance with an HTTP request and response along with promises + * for the serialized request and response body content. + * + * @param request the HTTP request + * @param response the HTTP response + * @param requestBody capture of serialized request body content + * @param responseBody capture of serialized response body content + * @param uriTemplate the URI template used to set up the request, if any */ - ExchangeResult(WiretapClientHttpRequest request, WiretapClientHttpResponse response) { + ExchangeResult(ClientHttpRequest request, ClientHttpResponse response, + MonoProcessor requestBody, MonoProcessor responseBody, + @Nullable String uriTemplate) { + + Assert.notNull(request, "ClientHttpRequest is required"); + Assert.notNull(response, "ClientHttpResponse is required"); + Assert.notNull(requestBody, "'requestBody' is required"); + Assert.notNull(responseBody, "'responseBody' is required"); + this.request = request; this.response = response; - this.uriTemplate = null; - } - - /** - * Constructor to copy the from the yet undecoded ExchangeResult with extra - * information to expose such as the original URI template used, if any. - */ - ExchangeResult(ExchangeResult other, @Nullable String uriTemplate) { - this.request = other.request; - this.response = other.response; + this.requestBody = requestBody; + this.responseBody = responseBody; this.uriTemplate = uriTemplate; } @@ -92,6 +104,8 @@ public class ExchangeResult { ExchangeResult(ExchangeResult other) { this.request = other.request; this.response = other.response; + this.requestBody = other.requestBody; + this.responseBody = other.responseBody; this.uriTemplate = other.uriTemplate; } @@ -131,7 +145,7 @@ public class ExchangeResult { */ @Nullable public byte[] getRequestBodyContent() { - MonoProcessor body = this.request.getRecordedContent(); + MonoProcessor body = this.requestBody; Assert.isTrue(body.isTerminated(), "Request body incomplete."); return body.block(Duration.ZERO); } @@ -164,7 +178,7 @@ public class ExchangeResult { */ @Nullable public byte[] getResponseBodyContent() { - MonoProcessor body = this.response.getRecordedContent(); + MonoProcessor body = this.responseBody; Assert.state(body.isTerminated(), "Response body incomplete"); return body.block(Duration.ZERO); } @@ -191,12 +205,12 @@ public class ExchangeResult { "> " + getMethod() + " " + getUrl() + "\n" + "> " + formatHeaders(getRequestHeaders(), "\n> ") + "\n" + "\n" + - formatBody(getRequestHeaders().getContentType(), this.request.getRecordedContent()) + "\n" + + formatBody(getRequestHeaders().getContentType(), this.requestBody) + "\n" + "\n" + "< " + getStatus() + " " + getStatusReason() + "\n" + "< " + formatHeaders(getResponseHeaders(), "\n< ") + "\n" + "\n" + - formatBody(getResponseHeaders().getContentType(), this.response.getRecordedContent()) +"\n"; + formatBody(getResponseHeaders().getContentType(), this.responseBody) +"\n"; } private String getStatusReason() { diff --git a/spring-test/src/main/java/org/springframework/test/web/reactive/server/WiretapClientHttpRequest.java b/spring-test/src/main/java/org/springframework/test/web/reactive/server/WiretapClientHttpRequest.java deleted file mode 100644 index 5abac89629..0000000000 --- a/spring-test/src/main/java/org/springframework/test/web/reactive/server/WiretapClientHttpRequest.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright 2002-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.test.web.reactive.server; - -import org.reactivestreams.Publisher; -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; -import reactor.core.publisher.MonoProcessor; - -import org.springframework.core.io.buffer.DataBuffer; -import org.springframework.core.io.buffer.DataBufferFactory; -import org.springframework.core.io.buffer.DefaultDataBufferFactory; -import org.springframework.http.client.reactive.ClientHttpRequest; -import org.springframework.http.client.reactive.ClientHttpRequestDecorator; - -/** - * Client HTTP request decorator that intercepts and saves content written to - * the server. - * - * @author Rossen Stoyanchev - * @since 5.0 - */ -class WiretapClientHttpRequest extends ClientHttpRequestDecorator { - - private static final DataBufferFactory bufferFactory = new DefaultDataBufferFactory(); - - - private final DataBuffer buffer; - - private final MonoProcessor body = MonoProcessor.create(); - - - public WiretapClientHttpRequest(ClientHttpRequest delegate) { - super(delegate); - this.buffer = bufferFactory.allocateBuffer(); - } - - - /** - * Return a "promise" with the request body content written to the server. - */ - public MonoProcessor getRecordedContent() { - return this.body; - } - - - @Override - public Mono writeWith(Publisher publisher) { - return super.writeWith( - Flux.from(publisher) - .doOnNext(this::handleOnNext) - .doOnError(this::handleError) - .doOnCancel(this::handleOnComplete) - .doOnComplete(this::handleOnComplete)); - } - - @Override - public Mono writeAndFlushWith(Publisher> publisher) { - return super.writeAndFlushWith( - Flux.from(publisher) - .map(p -> Flux.from(p).doOnNext(this::handleOnNext).doOnError(this::handleError)) - .doOnError(this::handleError) - .doOnCancel(this::handleOnComplete) - .doOnComplete(this::handleOnComplete)); - } - - @Override - public Mono setComplete() { - handleOnComplete(); - return super.setComplete(); - } - - private void handleOnNext(DataBuffer buffer) { - this.buffer.write(buffer); - } - - private void handleError(Throwable ex) { - if (!this.body.isTerminated()) { - this.body.onError(ex); - } - } - - private void handleOnComplete() { - if (!this.body.isTerminated()) { - byte[] bytes = new byte[this.buffer.readableByteCount()]; - this.buffer.read(bytes); - this.body.onNext(bytes); - } - } - -} diff --git a/spring-test/src/main/java/org/springframework/test/web/reactive/server/WiretapClientHttpResponse.java b/spring-test/src/main/java/org/springframework/test/web/reactive/server/WiretapClientHttpResponse.java deleted file mode 100644 index 63213ed1b6..0000000000 --- a/spring-test/src/main/java/org/springframework/test/web/reactive/server/WiretapClientHttpResponse.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright 2002-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.test.web.reactive.server; - -import reactor.core.publisher.Flux; -import reactor.core.publisher.MonoProcessor; - -import org.springframework.core.io.buffer.DataBuffer; -import org.springframework.core.io.buffer.DataBufferFactory; -import org.springframework.core.io.buffer.DefaultDataBufferFactory; -import org.springframework.http.client.reactive.ClientHttpResponse; -import org.springframework.http.client.reactive.ClientHttpResponseDecorator; - -/** - * Client HTTP response decorator that intercepts and saves the content read - * from the server. - * - * @author Rossen Stoyanchev - * @since 5.0 - */ -class WiretapClientHttpResponse extends ClientHttpResponseDecorator { - - private static final DataBufferFactory bufferFactory = new DefaultDataBufferFactory(); - - - private final DataBuffer buffer; - - private final MonoProcessor body = MonoProcessor.create(); - - - public WiretapClientHttpResponse(ClientHttpResponse delegate) { - super(delegate); - this.buffer = bufferFactory.allocateBuffer(); - } - - - /** - * Return a "promise" with the response body content read from the server. - */ - public MonoProcessor getRecordedContent() { - return this.body; - } - - @Override - public Flux getBody() { - return super.getBody() - .doOnNext(buffer::write) - .doOnError(body::onError) - .doOnCancel(this::handleOnComplete) - .doOnComplete(this::handleOnComplete); - } - - private void handleOnComplete() { - if (!this.body.isTerminated()) { - byte[] bytes = new byte[this.buffer.readableByteCount()]; - this.buffer.read(bytes); - this.body.onNext(bytes); - } - } - -} diff --git a/spring-test/src/main/java/org/springframework/test/web/reactive/server/WiretapConnector.java b/spring-test/src/main/java/org/springframework/test/web/reactive/server/WiretapConnector.java index 709dcaf293..b614c44b0a 100644 --- a/spring-test/src/main/java/org/springframework/test/web/reactive/server/WiretapConnector.java +++ b/spring-test/src/main/java/org/springframework/test/web/reactive/server/WiretapConnector.java @@ -22,12 +22,21 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicReference; import java.util.function.Function; +import org.reactivestreams.Publisher; +import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; +import reactor.core.publisher.MonoProcessor; +import org.springframework.core.io.buffer.DataBuffer; +import org.springframework.core.io.buffer.DataBufferFactory; +import org.springframework.core.io.buffer.DefaultDataBufferFactory; import org.springframework.http.HttpMethod; import org.springframework.http.client.reactive.ClientHttpConnector; import org.springframework.http.client.reactive.ClientHttpRequest; +import org.springframework.http.client.reactive.ClientHttpRequestDecorator; import org.springframework.http.client.reactive.ClientHttpResponse; +import org.springframework.http.client.reactive.ClientHttpResponseDecorator; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -41,9 +50,12 @@ import org.springframework.util.Assert; */ class WiretapConnector implements ClientHttpConnector { + private static final DataBufferFactory bufferFactory = new DefaultDataBufferFactory(); + + private final ClientHttpConnector delegate; - private final Map exchanges = new ConcurrentHashMap<>(); + private final Map exchanges = new ConcurrentHashMap<>(); WiretapConnector(ClientHttpConnector delegate) { @@ -65,22 +77,157 @@ class WiretapConnector implements ClientHttpConnector { }) .map(response -> { WiretapClientHttpRequest wrappedRequest = requestRef.get(); - String requestId = wrappedRequest.getHeaders().getFirst(WebTestClient.WEBTESTCLIENT_REQUEST_ID); - Assert.state(requestId != null, () -> "No \"" + WebTestClient.WEBTESTCLIENT_REQUEST_ID + "\" header"); + String header = WebTestClient.WEBTESTCLIENT_REQUEST_ID; + String requestId = wrappedRequest.getHeaders().getFirst(header); + Assert.state(requestId != null, () -> "No \"" + header + "\" header"); WiretapClientHttpResponse wrappedResponse = new WiretapClientHttpResponse(response); - ExchangeResult result = new ExchangeResult(wrappedRequest, wrappedResponse); - this.exchanges.put(requestId, result); + this.exchanges.put(requestId, new Info(wrappedRequest, wrappedResponse)); return wrappedResponse; }); } /** - * Retrieve the {@code ExchangeResult} for the given "request-id" header value. + * Retrieve the {@link Info} for the given "request-id" header value. */ - public ExchangeResult claimRequest(String requestId) { - ExchangeResult result = this.exchanges.remove(requestId); - Assert.state(result != null, () -> "No match for " + WebTestClient.WEBTESTCLIENT_REQUEST_ID + "=" + requestId); - return result; + public Info claimRequest(String requestId) { + Info info = this.exchanges.remove(requestId); + Assert.state(info != null, () -> { + String header = WebTestClient.WEBTESTCLIENT_REQUEST_ID; + return "No match for " + header + "=" + requestId; + }); + return info; + } + + + class Info { + + private final WiretapClientHttpRequest request; + + private final WiretapClientHttpResponse response; + + + public Info(WiretapClientHttpRequest request, WiretapClientHttpResponse response) { + this.request = request; + this.response = response; + } + + + public ExchangeResult createExchangeResult(@Nullable String uriTemplate) { + return new ExchangeResult(this.request, this.response, + this.request.getContent(), this.response.getContent(), uriTemplate); + } + } + + + /** + * ClientHttpRequestDecorator that intercepts and saves the request body. + */ + private static class WiretapClientHttpRequest extends ClientHttpRequestDecorator { + + private final DataBuffer buffer; + + private final MonoProcessor body = MonoProcessor.create(); + + + public WiretapClientHttpRequest(ClientHttpRequest delegate) { + super(delegate); + this.buffer = bufferFactory.allocateBuffer(); + } + + + /** + * Return a "promise" with the request body content written to the server. + */ + public MonoProcessor getContent() { + return this.body; + } + + + @Override + public Mono writeWith(Publisher publisher) { + return super.writeWith( + Flux.from(publisher) + .doOnNext(this::handleOnNext) + .doOnError(this::handleError) + .doOnCancel(this::handleOnComplete) + .doOnComplete(this::handleOnComplete)); + } + + @Override + public Mono writeAndFlushWith(Publisher> publisher) { + return super.writeAndFlushWith( + Flux.from(publisher) + .map(p -> Flux.from(p).doOnNext(this::handleOnNext).doOnError(this::handleError)) + .doOnError(this::handleError) + .doOnCancel(this::handleOnComplete) + .doOnComplete(this::handleOnComplete)); + } + + @Override + public Mono setComplete() { + handleOnComplete(); + return super.setComplete(); + } + + private void handleOnNext(DataBuffer buffer) { + this.buffer.write(buffer); + } + + private void handleError(Throwable ex) { + if (!this.body.isTerminated()) { + this.body.onError(ex); + } + } + + private void handleOnComplete() { + if (!this.body.isTerminated()) { + byte[] bytes = new byte[this.buffer.readableByteCount()]; + this.buffer.read(bytes); + this.body.onNext(bytes); + } + } + } + + + /** + * ClientHttpResponseDecorator that intercepts and saves the response body. + */ + private static class WiretapClientHttpResponse extends ClientHttpResponseDecorator { + + private final DataBuffer buffer; + + private final MonoProcessor body = MonoProcessor.create(); + + + public WiretapClientHttpResponse(ClientHttpResponse delegate) { + super(delegate); + this.buffer = bufferFactory.allocateBuffer(); + } + + + /** + * Return a "promise" with the response body content read from the server. + */ + public MonoProcessor getContent() { + return this.body; + } + + @Override + public Flux getBody() { + return super.getBody() + .doOnNext(buffer::write) + .doOnError(body::onError) + .doOnCancel(this::handleOnComplete) + .doOnComplete(this::handleOnComplete); + } + + private void handleOnComplete() { + if (!this.body.isTerminated()) { + byte[] bytes = new byte[this.buffer.readableByteCount()]; + this.buffer.read(bytes); + this.body.onNext(bytes); + } + } } } diff --git a/spring-test/src/test/java/org/springframework/test/web/reactive/server/HeaderAssertionsTests.java b/spring-test/src/test/java/org/springframework/test/web/reactive/server/HeaderAssertionsTests.java index 9b5889bacd..30b3afdeb9 100644 --- a/spring-test/src/test/java/org/springframework/test/web/reactive/server/HeaderAssertionsTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/reactive/server/HeaderAssertionsTests.java @@ -20,6 +20,7 @@ import java.net.URI; import java.util.concurrent.TimeUnit; import org.junit.Test; +import reactor.core.publisher.MonoProcessor; import org.springframework.http.CacheControl; import org.springframework.http.HttpHeaders; @@ -148,15 +149,14 @@ public class HeaderAssertionsTests { } private HeaderAssertions headerAssertions(HttpHeaders responseHeaders) { - MockClientHttpRequest request = new MockClientHttpRequest(HttpMethod.GET, URI.create("/")); MockClientHttpResponse response = new MockClientHttpResponse(HttpStatus.OK); response.getHeaders().putAll(responseHeaders); - WiretapClientHttpRequest wiretapRequest = new WiretapClientHttpRequest(request); - WiretapClientHttpResponse wiretapResponse = new WiretapClientHttpResponse(response); + MonoProcessor emptyContent = MonoProcessor.create(); + emptyContent.onComplete(); - ExchangeResult result = new ExchangeResult(wiretapRequest, wiretapResponse); + ExchangeResult result = new ExchangeResult(request, response, emptyContent, emptyContent, null); return new HeaderAssertions(result, mock(WebTestClient.ResponseSpec.class)); } diff --git a/spring-test/src/test/java/org/springframework/test/web/reactive/server/StatusAssertionTests.java b/spring-test/src/test/java/org/springframework/test/web/reactive/server/StatusAssertionTests.java index 84abce99d1..d688d041f2 100644 --- a/spring-test/src/test/java/org/springframework/test/web/reactive/server/StatusAssertionTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/reactive/server/StatusAssertionTests.java @@ -19,6 +19,7 @@ package org.springframework.test.web.reactive.server; import java.net.URI; import org.junit.Test; +import reactor.core.publisher.MonoProcessor; import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; @@ -161,15 +162,14 @@ public class StatusAssertionTests { private StatusAssertions statusAssertions(HttpStatus status) { - MockClientHttpRequest request = new MockClientHttpRequest(HttpMethod.GET, URI.create("/")); MockClientHttpResponse response = new MockClientHttpResponse(status); - WiretapClientHttpRequest wiretapRequest = new WiretapClientHttpRequest(request); - WiretapClientHttpResponse wiretapResponse = new WiretapClientHttpResponse(response); + MonoProcessor emptyContent = MonoProcessor.create(); + emptyContent.onComplete(); - ExchangeResult exchangeResult = new ExchangeResult(wiretapRequest, wiretapResponse); - return new StatusAssertions(exchangeResult, mock(WebTestClient.ResponseSpec.class)); + ExchangeResult result = new ExchangeResult(request, response, emptyContent, emptyContent, null); + return new StatusAssertions(result, mock(WebTestClient.ResponseSpec.class)); } } diff --git a/spring-test/src/test/java/org/springframework/test/web/reactive/server/WebTestClientConnectorTests.java b/spring-test/src/test/java/org/springframework/test/web/reactive/server/WebTestClientConnectorTests.java index efac941808..08cb87ebe8 100644 --- a/spring-test/src/test/java/org/springframework/test/web/reactive/server/WebTestClientConnectorTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/reactive/server/WebTestClientConnectorTests.java @@ -32,8 +32,8 @@ import org.springframework.web.reactive.function.client.ClientRequest; import org.springframework.web.reactive.function.client.ExchangeFunction; import org.springframework.web.reactive.function.client.ExchangeFunctions; -import static java.time.Duration.*; -import static org.junit.Assert.*; +import static java.time.Duration.ofMillis; +import static org.junit.Assert.assertEquals; /** * Unit tests for {@link WiretapConnector}. @@ -56,10 +56,10 @@ public class WebTestClientConnectorTests { ExchangeFunction function = ExchangeFunctions.create(wiretapConnector); function.exchange(clientRequest).block(ofMillis(0)); - ExchangeResult actual = wiretapConnector.claimRequest("1"); - assertNotNull(actual); - assertEquals(HttpMethod.GET, actual.getMethod()); - assertEquals("/test", actual.getUrl().toString()); + WiretapConnector.Info actual = wiretapConnector.claimRequest("1"); + ExchangeResult result = actual.createExchangeResult(null); + assertEquals(HttpMethod.GET, result.getMethod()); + assertEquals("/test", result.getUrl().toString()); } } diff --git a/spring-test/src/test/java/org/springframework/test/web/reactive/server/samples/ResponseEntityTests.java b/spring-test/src/test/java/org/springframework/test/web/reactive/server/samples/ResponseEntityTests.java index c7c14571d5..7d39d9817a 100644 --- a/spring-test/src/test/java/org/springframework/test/web/reactive/server/samples/ResponseEntityTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/reactive/server/samples/ResponseEntityTests.java @@ -40,7 +40,8 @@ import org.springframework.web.bind.annotation.RestController; import static java.time.Duration.ofMillis; import static org.hamcrest.CoreMatchers.endsWith; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; import static org.springframework.http.MediaType.TEXT_EVENT_STREAM; /**