Skip to content

Commit a982123

Browse files
committed
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<byte[]>. 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
1 parent 7e8c8f0 commit a982123

File tree

9 files changed

+220
-238
lines changed

9 files changed

+220
-238
lines changed

spring-test/src/main/java/org/springframework/test/web/reactive/server/DefaultWebTestClient.java

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -281,50 +281,50 @@ public RequestHeadersSpec<?> syncBody(Object body) {
281281
public ResponseSpec exchange() {
282282
ClientResponse clientResponse = this.bodySpec.exchange().block(getTimeout());
283283
Assert.state(clientResponse != null, "No ClientResponse");
284-
ExchangeResult exchangeResult = wiretapConnector.claimRequest(this.requestId);
285-
return new DefaultResponseSpec(exchangeResult, clientResponse, this.uriTemplate, getTimeout());
284+
WiretapConnector.Info info = wiretapConnector.claimRequest(this.requestId);
285+
return new DefaultResponseSpec(info, clientResponse, this.uriTemplate, getTimeout());
286286
}
287287
}
288288

289289

290290
private static class DefaultResponseSpec implements ResponseSpec {
291291

292-
private final ExchangeResult result;
292+
private final ExchangeResult exchangeResult;
293293

294294
private final ClientResponse response;
295295

296296
private final Duration timeout;
297297

298298

299-
DefaultResponseSpec(ExchangeResult result, ClientResponse response,
299+
DefaultResponseSpec(WiretapConnector.Info wiretapInfo, ClientResponse response,
300300
@Nullable String uriTemplate, Duration timeout) {
301301

302-
this.result = new ExchangeResult(result, uriTemplate);
302+
this.exchangeResult = wiretapInfo.createExchangeResult(uriTemplate);
303303
this.response = response;
304304
this.timeout = timeout;
305305
}
306306

307307
@Override
308308
public StatusAssertions expectStatus() {
309-
return new StatusAssertions(this.result, this);
309+
return new StatusAssertions(this.exchangeResult, this);
310310
}
311311

312312
@Override
313313
public HeaderAssertions expectHeader() {
314-
return new HeaderAssertions(this.result, this);
314+
return new HeaderAssertions(this.exchangeResult, this);
315315
}
316316

317317
@Override
318318
public <B> BodySpec<B, ?> expectBody(Class<B> bodyType) {
319319
B body = this.response.bodyToMono(bodyType).block(this.timeout);
320-
EntityExchangeResult<B> entityResult = new EntityExchangeResult<>(this.result, body);
320+
EntityExchangeResult<B> entityResult = new EntityExchangeResult<>(this.exchangeResult, body);
321321
return new DefaultBodySpec<>(entityResult);
322322
}
323323

324324
@Override
325325
public <B> BodySpec<B, ?> expectBody(ParameterizedTypeReference<B> bodyType) {
326326
B body = this.response.bodyToMono(bodyType).block(this.timeout);
327-
EntityExchangeResult<B> entityResult = new EntityExchangeResult<>(this.result, body);
327+
EntityExchangeResult<B> entityResult = new EntityExchangeResult<>(this.exchangeResult, body);
328328
return new DefaultBodySpec<>(entityResult);
329329
}
330330

@@ -341,28 +341,28 @@ public <E> ListBodySpec<E> expectBodyList(ParameterizedTypeReference<E> elementT
341341

342342
private <E> ListBodySpec<E> getListBodySpec(Flux<E> flux) {
343343
List<E> body = flux.collectList().block(this.timeout);
344-
EntityExchangeResult<List<E>> entityResult = new EntityExchangeResult<>(this.result, body);
344+
EntityExchangeResult<List<E>> entityResult = new EntityExchangeResult<>(this.exchangeResult, body);
345345
return new DefaultListBodySpec<>(entityResult);
346346
}
347347

348348
@Override
349349
public BodyContentSpec expectBody() {
350350
ByteArrayResource resource = this.response.bodyToMono(ByteArrayResource.class).block(this.timeout);
351351
byte[] body = (resource != null ? resource.getByteArray() : null);
352-
EntityExchangeResult<byte[]> entityResult = new EntityExchangeResult<>(this.result, body);
352+
EntityExchangeResult<byte[]> entityResult = new EntityExchangeResult<>(this.exchangeResult, body);
353353
return new DefaultBodyContentSpec(entityResult);
354354
}
355355

356356
@Override
357357
public <T> FluxExchangeResult<T> returnResult(Class<T> elementType) {
358358
Flux<T> body = this.response.bodyToFlux(elementType);
359-
return new FluxExchangeResult<>(this.result, body, this.timeout);
359+
return new FluxExchangeResult<>(this.exchangeResult, body, this.timeout);
360360
}
361361

362362
@Override
363363
public <T> FluxExchangeResult<T> returnResult(ParameterizedTypeReference<T> elementType) {
364364
Flux<T> body = this.response.bodyToFlux(elementType);
365-
return new FluxExchangeResult<>(this.result, body, this.timeout);
365+
return new FluxExchangeResult<>(this.exchangeResult, body, this.timeout);
366366
}
367367
}
368368

spring-test/src/main/java/org/springframework/test/web/reactive/server/ExchangeResult.java

Lines changed: 33 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131
import org.springframework.http.HttpStatus;
3232
import org.springframework.http.MediaType;
3333
import org.springframework.http.ResponseCookie;
34+
import org.springframework.http.client.reactive.ClientHttpRequest;
35+
import org.springframework.http.client.reactive.ClientHttpResponse;
3436
import org.springframework.lang.Nullable;
3537
import org.springframework.util.Assert;
3638
import org.springframework.util.MultiValueMap;
@@ -58,31 +60,41 @@ public class ExchangeResult {
5860
MediaType.parseMediaType("text/*"), MediaType.APPLICATION_FORM_URLENCODED);
5961

6062

61-
private final WiretapClientHttpRequest request;
63+
private final ClientHttpRequest request;
6264

63-
private final WiretapClientHttpResponse response;
65+
private final ClientHttpResponse response;
66+
67+
private final MonoProcessor<byte[]> requestBody;
68+
69+
private final MonoProcessor<byte[]> responseBody;
6470

6571
@Nullable
6672
private final String uriTemplate;
6773

6874

6975
/**
70-
* Constructor to use after the server response is first received in the
71-
* {@link WiretapConnector} and the {@code ClientHttpResponse} created.
76+
* Create an instance with an HTTP request and response along with promises
77+
* for the serialized request and response body content.
78+
*
79+
* @param request the HTTP request
80+
* @param response the HTTP response
81+
* @param requestBody capture of serialized request body content
82+
* @param responseBody capture of serialized response body content
83+
* @param uriTemplate the URI template used to set up the request, if any
7284
*/
73-
ExchangeResult(WiretapClientHttpRequest request, WiretapClientHttpResponse response) {
85+
ExchangeResult(ClientHttpRequest request, ClientHttpResponse response,
86+
MonoProcessor<byte[]> requestBody, MonoProcessor<byte[]> responseBody,
87+
@Nullable String uriTemplate) {
88+
89+
Assert.notNull(request, "ClientHttpRequest is required");
90+
Assert.notNull(response, "ClientHttpResponse is required");
91+
Assert.notNull(requestBody, "'requestBody' is required");
92+
Assert.notNull(responseBody, "'responseBody' is required");
93+
7494
this.request = request;
7595
this.response = response;
76-
this.uriTemplate = null;
77-
}
78-
79-
/**
80-
* Constructor to copy the from the yet undecoded ExchangeResult with extra
81-
* information to expose such as the original URI template used, if any.
82-
*/
83-
ExchangeResult(ExchangeResult other, @Nullable String uriTemplate) {
84-
this.request = other.request;
85-
this.response = other.response;
96+
this.requestBody = requestBody;
97+
this.responseBody = responseBody;
8698
this.uriTemplate = uriTemplate;
8799
}
88100

@@ -92,6 +104,8 @@ public class ExchangeResult {
92104
ExchangeResult(ExchangeResult other) {
93105
this.request = other.request;
94106
this.response = other.response;
107+
this.requestBody = other.requestBody;
108+
this.responseBody = other.responseBody;
95109
this.uriTemplate = other.uriTemplate;
96110
}
97111

@@ -131,7 +145,7 @@ public HttpHeaders getRequestHeaders() {
131145
*/
132146
@Nullable
133147
public byte[] getRequestBodyContent() {
134-
MonoProcessor<byte[]> body = this.request.getRecordedContent();
148+
MonoProcessor<byte[]> body = this.requestBody;
135149
Assert.isTrue(body.isTerminated(), "Request body incomplete.");
136150
return body.block(Duration.ZERO);
137151
}
@@ -164,7 +178,7 @@ public MultiValueMap<String, ResponseCookie> getResponseCookies() {
164178
*/
165179
@Nullable
166180
public byte[] getResponseBodyContent() {
167-
MonoProcessor<byte[]> body = this.response.getRecordedContent();
181+
MonoProcessor<byte[]> body = this.responseBody;
168182
Assert.state(body.isTerminated(), "Response body incomplete");
169183
return body.block(Duration.ZERO);
170184
}
@@ -191,12 +205,12 @@ public String toString() {
191205
"> " + getMethod() + " " + getUrl() + "\n" +
192206
"> " + formatHeaders(getRequestHeaders(), "\n> ") + "\n" +
193207
"\n" +
194-
formatBody(getRequestHeaders().getContentType(), this.request.getRecordedContent()) + "\n" +
208+
formatBody(getRequestHeaders().getContentType(), this.requestBody) + "\n" +
195209
"\n" +
196210
"< " + getStatus() + " " + getStatusReason() + "\n" +
197211
"< " + formatHeaders(getResponseHeaders(), "\n< ") + "\n" +
198212
"\n" +
199-
formatBody(getResponseHeaders().getContentType(), this.response.getRecordedContent()) +"\n";
213+
formatBody(getResponseHeaders().getContentType(), this.responseBody) +"\n";
200214
}
201215

202216
private String getStatusReason() {

spring-test/src/main/java/org/springframework/test/web/reactive/server/WiretapClientHttpRequest.java

Lines changed: 0 additions & 105 deletions
This file was deleted.

spring-test/src/main/java/org/springframework/test/web/reactive/server/WiretapClientHttpResponse.java

Lines changed: 0 additions & 75 deletions
This file was deleted.

0 commit comments

Comments
 (0)