@@ -253,56 +253,76 @@ public <T, S extends Publisher<T>> ResponseSpec exchange(S publisher, Class<T> e
253
253
return toResponseSpec (this .headerSpec .exchange (publisher , elementClass ));
254
254
}
255
255
256
- private DefaultResponseSpec toResponseSpec (Mono <ClientResponse > responseMono ) {
257
- ClientResponse response = responseMono .block (getTimeout ());
258
- ClientHttpRequest request = webTestClientConnector .claimRequest (this .requestId );
259
- ExchangeResult <Flux <DataBuffer >> result = ExchangeResult .create (request , response );
260
- return new DefaultResponseSpec (result , response );
256
+ private DefaultResponseSpec toResponseSpec (Mono <ClientResponse > mono ) {
257
+ ClientResponse response = mono .block (getTimeout ());
258
+ ClientHttpRequest httpRequest = webTestClientConnector .claimRequest (this .requestId );
259
+ return new DefaultResponseSpec (httpRequest , response );
261
260
}
262
261
}
263
262
264
- private abstract class ResponseSpecSupport {
265
-
266
- private final ExchangeResult <Flux <DataBuffer >> exchangeResult ;
263
+ /**
264
+ * ExchangeResult that contains the live {@link ClientResponse}.
265
+ */
266
+ private class UndecodedExchangeResult extends ExchangeResult {
267
267
268
268
private final ClientResponse response ;
269
269
270
270
271
- public ResponseSpecSupport ( ExchangeResult < Flux < DataBuffer >> result , ClientResponse response ) {
272
- this . exchangeResult = result ;
271
+ public UndecodedExchangeResult ( ClientHttpRequest httpRequest , ClientResponse response ) {
272
+ super ( httpRequest , response ) ;
273
273
this .response = response ;
274
274
}
275
275
276
276
277
- protected ExchangeResult <Flux <DataBuffer >> getExchangeResult () {
278
- return this .exchangeResult ;
277
+ public EntityExchangeResult <?> consumeSingle (ResolvableType elementType ) {
278
+ Object body = this .response .body (toMono (elementType )).block (getTimeout ());
279
+ return new EntityExchangeResult <>(this , body );
279
280
}
280
281
281
- protected ClientResponse getResponse () {
282
- return this .response ;
282
+ public EntityExchangeResult <List <?>> consumeList (ResolvableType elementType , int count ) {
283
+ Flux <?> flux = this .response .body (toFlux (elementType ));
284
+ if (count >= 0 ) {
285
+ flux = flux .take (count );
286
+ }
287
+ List <?> body = flux .collectList ().block (getTimeout ());
288
+ return new EntityExchangeResult <>(this , body );
283
289
}
284
290
285
- protected <T > ExchangeResult <T > createResultWithDecodedBody (T body ) {
286
- return ExchangeResult .withDecodedBody (this .exchangeResult , body );
291
+ public <T > FluxExchangeResult <T > decodeBody (ResolvableType elementType ) {
292
+ Flux <T > body = this .response .body (toFlux (elementType ));
293
+ return new FluxExchangeResult <>(this , body , elementType );
287
294
}
288
295
296
+ @ SuppressWarnings ("unchecked" )
297
+ public EntityExchangeResult <Map <?, ?>> consumeMap (ResolvableType keyType , ResolvableType valueType ) {
298
+ ResolvableType mapType = ResolvableType .forClassWithGenerics (Map .class , keyType , valueType );
299
+ return (EntityExchangeResult <Map <?, ?>>) consumeSingle (mapType );
300
+ }
301
+
302
+ public EntityExchangeResult <Void > consumeEmpty () {
303
+ DataBuffer buffer = this .response .body (toDataBuffers ()).blockFirst (getTimeout ());
304
+ assertTrue ("Expected empty body" , buffer == null );
305
+ return new EntityExchangeResult <>(this , null );
306
+ }
289
307
}
290
308
291
- private class DefaultResponseSpec extends ResponseSpecSupport implements ResponseSpec {
309
+ private class DefaultResponseSpec implements ResponseSpec {
292
310
311
+ private final UndecodedExchangeResult exchangeResult ;
293
312
294
- public DefaultResponseSpec (ExchangeResult <Flux <DataBuffer >> exchangeResult , ClientResponse response ) {
295
- super (exchangeResult , response );
313
+
314
+ public DefaultResponseSpec (ClientHttpRequest httpRequest , ClientResponse response ) {
315
+ this .exchangeResult = new UndecodedExchangeResult (httpRequest , response );
296
316
}
297
317
298
318
@ Override
299
319
public StatusAssertions expectStatus () {
300
- return new StatusAssertions (getExchangeResult () , this );
320
+ return new StatusAssertions (this . exchangeResult , this );
301
321
}
302
322
303
323
@ Override
304
324
public HeaderAssertions expectHeader () {
305
- return new HeaderAssertions (getExchangeResult () , this );
325
+ return new HeaderAssertions (this . exchangeResult , this );
306
326
}
307
327
308
328
@ Override
@@ -312,40 +332,43 @@ public TypeBodySpec expectBody(Class<?> elementType) {
312
332
313
333
@ Override
314
334
public TypeBodySpec expectBody (ResolvableType elementType ) {
315
- return new DefaultTypeBodySpec (this , elementType );
335
+ return new DefaultTypeBodySpec (this . exchangeResult , elementType );
316
336
}
317
337
318
338
@ Override
319
339
public BodySpec expectBody () {
320
- return new DefaultBodySpec (this );
340
+ return new DefaultBodySpec (this . exchangeResult );
321
341
}
322
342
323
343
@ Override
324
- public ResponseSpec consumeWith (Consumer <ExchangeResult < Flux < DataBuffer >> > consumer ) {
325
- consumer .accept (getExchangeResult () );
344
+ public ResponseSpec consumeWith (Consumer <ExchangeResult > consumer ) {
345
+ consumer .accept (this . exchangeResult );
326
346
return this ;
327
347
}
328
348
329
349
@ Override
330
- public ExchangeResult < Flux < DataBuffer >> returnResult () {
331
- return getExchangeResult () ;
350
+ public ExchangeResult returnResult () {
351
+ return this . exchangeResult ;
332
352
}
333
353
}
334
354
335
- private class DefaultTypeBodySpec extends ResponseSpecSupport implements TypeBodySpec {
355
+ private class DefaultTypeBodySpec implements TypeBodySpec {
356
+
357
+ private final UndecodedExchangeResult exchangeResult ;
336
358
337
359
private final ResolvableType elementType ;
338
360
339
361
340
- public DefaultTypeBodySpec (DefaultResponseSpec spec , ResolvableType elementType ) {
341
- super ( spec . getExchangeResult (), spec . getResponse ()) ;
362
+ public DefaultTypeBodySpec (UndecodedExchangeResult result , ResolvableType elementType ) {
363
+ this . exchangeResult = result ;
342
364
this .elementType = elementType ;
343
365
}
344
366
345
367
346
368
@ Override
347
369
public SingleValueBodySpec value () {
348
- return new DefaultSingleValueBodySpec (this , this .elementType );
370
+ EntityExchangeResult <?> completed = this .exchangeResult .consumeSingle (this .elementType );
371
+ return new DefaultSingleValueBodySpec (completed );
349
372
}
350
373
351
374
@ Override
@@ -354,59 +377,52 @@ public ListBodySpec list() {
354
377
}
355
378
356
379
@ Override
357
- public ListBodySpec list (int elementCount ) {
358
- return new DefaultListBodySpec (this , this .elementType , elementCount );
380
+ public ListBodySpec list (int count ) {
381
+ EntityExchangeResult <List <?>> completed = this .exchangeResult .consumeList (this .elementType , count );
382
+ return new DefaultListBodySpec (completed );
359
383
}
360
384
361
385
@ Override
362
- public <T > ExchangeResult <Flux <T >> returnResult () {
363
- Flux <T > flux = getResponse ().body (toFlux (this .elementType ));
364
- return createResultWithDecodedBody (flux );
386
+ public <T > FluxExchangeResult <T > returnResult () {
387
+ return this .exchangeResult .decodeBody (this .elementType );
365
388
}
366
389
}
367
390
368
- private class DefaultSingleValueBodySpec extends ResponseSpecSupport implements SingleValueBodySpec {
391
+ private class DefaultSingleValueBodySpec implements SingleValueBodySpec {
369
392
370
- private final Object body ;
393
+ private final EntityExchangeResult <?> exchangeResult ;
371
394
372
395
373
- public DefaultSingleValueBodySpec (DefaultTypeBodySpec spec , ResolvableType elementType ) {
374
- super (spec .getExchangeResult (), spec .getResponse ());
375
- this .body = getResponse ().body (toMono (elementType )).block (getTimeout ());
396
+ public DefaultSingleValueBodySpec (EntityExchangeResult <?> result ) {
397
+ this .exchangeResult = result ;
376
398
}
377
399
378
400
379
401
@ Override
380
- public <T > ExchangeResult <T > isEqualTo (Object expected ) {
381
- assertEquals ("Response body" , expected , this .body );
402
+ public <T > EntityExchangeResult <T > isEqualTo (T expected ) {
403
+ assertEquals ("Response body" , expected , this .exchangeResult . getResponseBody () );
382
404
return returnResult ();
383
405
}
384
406
385
407
@ Override
386
- @ SuppressWarnings ("unchecked" )
387
- public <T > ExchangeResult <T > returnResult () {
388
- return createResultWithDecodedBody ((T ) this .body );
408
+ public <T > EntityExchangeResult <T > returnResult () {
409
+ return new EntityExchangeResult <>(this .exchangeResult , (T ) this .exchangeResult .getResponseBody ());
389
410
}
390
411
}
391
412
392
- private class DefaultListBodySpec extends ResponseSpecSupport implements ListBodySpec {
413
+ private class DefaultListBodySpec implements ListBodySpec {
393
414
394
- private final List <?> body ;
415
+ private final EntityExchangeResult < List <?>> exchangeResult ;
395
416
396
417
397
- public DefaultListBodySpec (DefaultTypeBodySpec spec , ResolvableType elementType , int elementCount ) {
398
- super (spec .getExchangeResult (), spec .getResponse ());
399
- Flux <?> flux = getResponse ().body (toFlux (elementType ));
400
- if (elementCount >= 0 ) {
401
- flux = flux .take (elementCount );
402
- }
403
- this .body = flux .collectList ().block (getTimeout ());
418
+ public DefaultListBodySpec (EntityExchangeResult <List <?>> result ) {
419
+ this .exchangeResult = result ;
404
420
}
405
421
406
422
407
423
@ Override
408
- public <T > ExchangeResult <List <T >> isEqualTo (List <T > expected ) {
409
- assertEquals ("Response body" , expected , this .body );
424
+ public <T > EntityExchangeResult <List <T >> isEqualTo (List <T > expected ) {
425
+ assertEquals ("Response body" , expected , this .exchangeResult . getResponseBody () );
410
426
return returnResult ();
411
427
}
412
428
@@ -419,38 +435,38 @@ public ListBodySpec hasSize(int size) {
419
435
public ListBodySpec contains (Object ... elements ) {
420
436
List <Object > elementList = Arrays .asList (elements );
421
437
String message = "Response body does not contain " + elementList ;
422
- assertTrue (message , this .body .containsAll (elementList ));
438
+ assertTrue (message , this .exchangeResult . getResponseBody () .containsAll (elementList ));
423
439
return this ;
424
440
}
425
441
426
442
@ Override
427
443
public ListBodySpec doesNotContain (Object ... elements ) {
428
444
List <Object > elementList = Arrays .asList (elements );
429
445
String message = "Response body should have contained " + elementList ;
430
- assertTrue (message , !this .body .containsAll (Arrays .asList (elements )));
446
+ assertTrue (message , !this .exchangeResult . getResponseBody () .containsAll (Arrays .asList (elements )));
431
447
return this ;
432
448
}
433
449
434
450
@ Override
435
451
@ SuppressWarnings ("unchecked" )
436
- public <T > ExchangeResult <List <T >> returnResult () {
437
- return createResultWithDecodedBody ( (List <T >) this .body );
452
+ public <T > EntityExchangeResult <List <T >> returnResult () {
453
+ return new EntityExchangeResult <>( this . exchangeResult , (List <T >) this .exchangeResult . getResponseBody () );
438
454
}
439
455
}
440
456
441
- private class DefaultBodySpec extends ResponseSpecSupport implements BodySpec {
457
+ private class DefaultBodySpec implements BodySpec {
458
+
459
+ private final UndecodedExchangeResult exchangeResult ;
442
460
443
461
444
- public DefaultBodySpec (DefaultResponseSpec spec ) {
445
- super ( spec . getExchangeResult (), spec . getResponse ()) ;
462
+ public DefaultBodySpec (UndecodedExchangeResult result ) {
463
+ this . exchangeResult = result ;
446
464
}
447
465
448
466
449
467
@ Override
450
- public ExchangeResult <Void > isEmpty () {
451
- DataBuffer buffer = getResponse ().body (toDataBuffers ()).blockFirst (getTimeout ());
452
- assertTrue ("Expected empty body" , buffer == null );
453
- return createResultWithDecodedBody (null );
468
+ public EntityExchangeResult <Void > isEmpty () {
469
+ return this .exchangeResult .consumeEmpty ();
454
470
}
455
471
456
472
@ Override
@@ -460,57 +476,61 @@ public MapBodySpec map(Class<?> keyType, Class<?> valueType) {
460
476
461
477
@ Override
462
478
public MapBodySpec map (ResolvableType keyType , ResolvableType valueType ) {
463
- return new DefaultMapBodySpec (this , keyType , valueType );
479
+ EntityExchangeResult <Map <?, ?>> completed = this .exchangeResult .consumeMap (keyType , valueType );
480
+ return new DefaultMapBodySpec (completed );
464
481
}
465
482
}
466
483
467
- private class DefaultMapBodySpec extends ResponseSpecSupport implements MapBodySpec {
484
+ private class DefaultMapBodySpec implements MapBodySpec {
468
485
469
- private final Map <?, ?> body ;
486
+ private final EntityExchangeResult < Map <?, ?>> exchangeResult ;
470
487
471
488
472
- public DefaultMapBodySpec (DefaultBodySpec spec , ResolvableType keyType , ResolvableType valueType ) {
473
- super (spec .getExchangeResult (), spec .getResponse ());
474
- ResolvableType mapType = ResolvableType .forClassWithGenerics (Map .class , keyType , valueType );
475
- this .body = (Map <?, ?>) spec .getResponse ().body (toMono (mapType )).block (getTimeout ());
489
+ public DefaultMapBodySpec (EntityExchangeResult <Map <?, ?>> result ) {
490
+ this .exchangeResult = result ;
476
491
}
477
492
478
493
494
+ private Map <?, ?> getBody () {
495
+ return this .exchangeResult .getResponseBody ();
496
+ }
497
+
479
498
@ Override
480
- public <K , V > ExchangeResult <Map <K , V >> isEqualTo (Map <K , V > expected ) {
499
+ public <K , V > EntityExchangeResult <Map <K , V >> isEqualTo (Map <K , V > expected ) {
500
+ assertEquals ("Response body map" , expected , getBody ());
481
501
return returnResult ();
482
502
}
483
503
484
504
@ Override
485
505
public MapBodySpec hasSize (int size ) {
486
- assertEquals ("Response body map size" , size , this . body .size ());
506
+ assertEquals ("Response body map size" , size , getBody () .size ());
487
507
return this ;
488
508
}
489
509
490
510
@ Override
491
511
public MapBodySpec contains (Object key , Object value ) {
492
- assertEquals ("Response body map value for key " + key , value , this . body .get (key ));
512
+ assertEquals ("Response body map value for key " + key , value , getBody () .get (key ));
493
513
return this ;
494
514
}
495
515
496
516
@ Override
497
517
public MapBodySpec containsKeys (Object ... keys ) {
498
- List <?> missing = Arrays .stream (keys ).filter (k -> !this . body .containsKey (k )).collect (toList ());
518
+ List <?> missing = Arrays .stream (keys ).filter (k -> !getBody () .containsKey (k )).collect (toList ());
499
519
assertTrue ("Response body map does not contain keys " + missing , missing .isEmpty ());
500
520
return this ;
501
521
}
502
522
503
523
@ Override
504
524
public MapBodySpec containsValues (Object ... values ) {
505
- List <?> missing = Arrays .stream (values ).filter (v -> !this . body .containsValue (v )).collect (toList ());
525
+ List <?> missing = Arrays .stream (values ).filter (v -> !getBody () .containsValue (v )).collect (toList ());
506
526
assertTrue ("Response body map does not contain values " + missing , missing .isEmpty ());
507
527
return this ;
508
528
}
509
529
510
530
@ Override
511
531
@ SuppressWarnings ("unchecked" )
512
- public <K , V > ExchangeResult <Map <K , V >> returnResult () {
513
- return createResultWithDecodedBody ( (Map <K , V >) this . body );
532
+ public <K , V > EntityExchangeResult <Map <K , V >> returnResult () {
533
+ return new EntityExchangeResult <>( this . exchangeResult , (Map <K , V >) getBody () );
514
534
}
515
535
}
516
536
0 commit comments