diff --git a/spring-test/src/main/java/org/springframework/test/web/reactive/server/ExchangeActions.java b/spring-test/src/main/java/org/springframework/test/web/reactive/server/ExchangeActions.java index 2fdf232ce4..6c0da4bc55 100644 --- a/spring-test/src/main/java/org/springframework/test/web/reactive/server/ExchangeActions.java +++ b/spring-test/src/main/java/org/springframework/test/web/reactive/server/ExchangeActions.java @@ -15,24 +15,16 @@ */ package org.springframework.test.web.reactive.server; -import java.nio.ByteBuffer; import java.time.Duration; import java.util.Collections; import java.util.List; -import java.util.Map; import java.util.function.Consumer; -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; -import reactor.test.StepVerifier; - import org.springframework.core.ResolvableType; import org.springframework.http.HttpHeaders; import org.springframework.test.util.AssertionErrors; import org.springframework.web.reactive.function.client.ClientResponse; -import static org.springframework.web.reactive.function.BodyExtractors.toMono; - /** * Entry point for applying assertions and actions on a performed exchange. * @@ -49,21 +41,12 @@ public final class ExchangeActions { } - private ClientResponse getResponse() { - return this.exchangeInfo.getResponse(); - } - - private Duration getResponseTimeout() { - return this.exchangeInfo.getResponseTimeout(); - } - - /** * Assert the status of the response. * @return further options for asserting the status of the response */ public ResponseStatusAssertions assertStatus() { - return new ResponseStatusAssertions(this, this.exchangeInfo); + return new ResponseStatusAssertions(this); } /** @@ -71,7 +54,8 @@ public final class ExchangeActions { * @return further options for asserting headers */ public ResponseHeadersAssertions assertHeaders() { - return new ResponseHeadersAssertions(this, getResponse().headers().asHttpHeaders()); + HttpHeaders headers = this.exchangeInfo.getResponse().headers().asHttpHeaders(); + return new ResponseHeadersAssertions(this, headers); } /** @@ -80,7 +64,7 @@ public final class ExchangeActions { * @return options for asserting the header value(s) */ public ResponseHeaderAssertions assertHeader(String headerName) { - HttpHeaders headers = getResponse().headers().asHttpHeaders(); + HttpHeaders headers = this.exchangeInfo.getResponse().headers().asHttpHeaders(); List values = headers.getOrDefault(headerName, Collections.emptyList()); return new ResponseHeaderAssertions(this, headerName, values); } @@ -88,10 +72,8 @@ public final class ExchangeActions { /** * Assert the response does not have any content. */ - public ExchangeActions assertBodyIsEmpty() { - Flux body = this.exchangeInfo.getResponse().bodyToFlux(ByteBuffer.class); - StepVerifier.create(body).expectComplete().verify(this.exchangeInfo.getResponseTimeout()); - return this; + public ResponseBodyAssertions assertBody() { + return new ResponseBodyAssertions(this); } /** @@ -107,24 +89,14 @@ public final class ExchangeActions { * @return further options for asserting response entities */ public ResponseEntityAssertions assertEntity(ResolvableType entityType) { - return new ResponseEntityAssertions(this, this.exchangeInfo, entityType); - } - - /** - * Assert the response decoded as a Map of the given key and value types. - */ - public MapAssertions assertBodyAsMap(Class keyType, Class valueType) { - ResolvableType type = ResolvableType.forClassWithGenerics(Map.class, keyType, valueType); - Mono> mono = this.exchangeInfo.getResponse().body(toMono(type)); - Map map = mono.block(this.exchangeInfo.getResponseTimeout()); - return new MapAssertions<>(this, map, "Response body map"); + return new ResponseEntityAssertions(this, entityType); } /** * Log debug information about the exchange. */ public LoggingExchangeConsumer log() { - return new LoggingExchangeConsumer(this, this.exchangeInfo); + return new LoggingExchangeConsumer(this); } /** diff --git a/spring-test/src/main/java/org/springframework/test/web/reactive/server/ListAssertions.java b/spring-test/src/main/java/org/springframework/test/web/reactive/server/ListAssertions.java index 7748629d47..ea34dc356a 100644 --- a/spring-test/src/main/java/org/springframework/test/web/reactive/server/ListAssertions.java +++ b/spring-test/src/main/java/org/springframework/test/web/reactive/server/ListAssertions.java @@ -22,7 +22,7 @@ import static org.springframework.test.util.AssertionErrors.assertEquals; import static org.springframework.test.util.AssertionErrors.assertTrue; /** - * Assertions on a collection of values. + * Assertions on a List of values. * * @param the type of element values in the collection * @@ -38,7 +38,7 @@ public class ListAssertions extends ObjectAssertions, ListAssertions< /** - * Assert the size of the collection. + * Assert the size of the list. */ public ListAssertions hasSize(int size) { assertEquals(getErrorPrefix() + " count", size, getValue().size()); @@ -46,7 +46,7 @@ public class ListAssertions extends ObjectAssertions, ListAssertions< } /** - * Assert that the collection contains all of the given values. + * Assert that the list contains all of the given values. */ @SuppressWarnings("unchecked") public ListAssertions contains(E... entities) { @@ -58,7 +58,7 @@ public class ListAssertions extends ObjectAssertions, ListAssertions< } /** - * Assert the collection does not contain any of the given values. + * Assert the list does not contain any of the given values. */ @SuppressWarnings("unchecked") public ListAssertions doesNotContain(E... entities) { diff --git a/spring-test/src/main/java/org/springframework/test/web/reactive/server/LoggingExchangeConsumer.java b/spring-test/src/main/java/org/springframework/test/web/reactive/server/LoggingExchangeConsumer.java index 65f9e5ef92..00357191c0 100644 --- a/spring-test/src/main/java/org/springframework/test/web/reactive/server/LoggingExchangeConsumer.java +++ b/spring-test/src/main/java/org/springframework/test/web/reactive/server/LoggingExchangeConsumer.java @@ -38,12 +38,9 @@ public class LoggingExchangeConsumer { private final ExchangeActions exchangeActions; - private final ExchangeInfo exchangeInfo; - - public LoggingExchangeConsumer(ExchangeActions exchangeActions, ExchangeInfo exchangeInfo) { + public LoggingExchangeConsumer(ExchangeActions exchangeActions) { this.exchangeActions = exchangeActions; - this.exchangeInfo = exchangeInfo; } @@ -51,7 +48,7 @@ public class LoggingExchangeConsumer { * Log with {@link System#out}. */ public ExchangeActions toConsole() { - System.out.println(this.exchangeInfo.toString()); + System.out.println(getOutput()); return this.exchangeActions; } @@ -67,7 +64,7 @@ public class LoggingExchangeConsumer { */ public ExchangeActions toWriter(Writer writer) { try { - writer.write(this.exchangeInfo.toString()); + writer.write(getOutput()); } catch (IOException ex) { throw new IllegalStateException("Failed to print exchange info", ex); @@ -98,9 +95,13 @@ public class LoggingExchangeConsumer { private ExchangeActions doLog(Predicate logLevelPredicate, BiConsumer logAction) { if (logLevelPredicate.test(logger)) { - logAction.accept(logger, this.exchangeInfo.toString()); + logAction.accept(logger, getOutput()); } return this.exchangeActions; } + private String getOutput() { + return this.exchangeActions.andReturn().toString(); + } + } diff --git a/spring-test/src/main/java/org/springframework/test/web/reactive/server/ObjectAssertions.java b/spring-test/src/main/java/org/springframework/test/web/reactive/server/ObjectAssertions.java index 2c7a3b7d6e..ee301af050 100644 --- a/spring-test/src/main/java/org/springframework/test/web/reactive/server/ObjectAssertions.java +++ b/spring-test/src/main/java/org/springframework/test/web/reactive/server/ObjectAssertions.java @@ -15,10 +15,12 @@ */ package org.springframework.test.web.reactive.server; +import java.time.Duration; import java.util.function.Consumer; import java.util.function.Supplier; import org.springframework.test.util.AssertionErrors; +import org.springframework.web.reactive.function.client.ClientResponse; import static org.springframework.test.util.AssertionErrors.assertEquals; @@ -113,6 +115,14 @@ public class ObjectAssertions> { return this.exchangeActions; } + protected ClientResponse getResponse() { + return this.exchangeActions.andReturn().getResponse(); + } + + protected Duration getTimeout() { + return this.exchangeActions.andReturn().getResponseTimeout(); + } + protected String getErrorPrefix() { return this.errorPrefix; } diff --git a/spring-test/src/main/java/org/springframework/test/web/reactive/server/ResponseBodyAssertions.java b/spring-test/src/main/java/org/springframework/test/web/reactive/server/ResponseBodyAssertions.java new file mode 100644 index 0000000000..6b51c7ef9b --- /dev/null +++ b/spring-test/src/main/java/org/springframework/test/web/reactive/server/ResponseBodyAssertions.java @@ -0,0 +1,74 @@ +/* + * 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 java.nio.ByteBuffer; +import java.time.Duration; +import java.util.Map; + +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; +import reactor.test.StepVerifier; + +import org.springframework.core.ResolvableType; +import org.springframework.web.reactive.function.client.ClientResponse; + +import static org.springframework.web.reactive.function.BodyExtractors.toMono; + +/** + * + * @author Rossen Stoyanchev + * @since 5.0 + */ +public class ResponseBodyAssertions { + + private final ExchangeActions exchangeActions; + + + public ResponseBodyAssertions(ExchangeActions exchangeActions) { + this.exchangeActions = exchangeActions; + } + + + /** + * Assert the response does not have any content. + */ + public ExchangeActions isEmpty() { + Flux body = getResponse().bodyToFlux(ByteBuffer.class); + StepVerifier.create(body).expectComplete().verify(getTimeout()); + return this.exchangeActions; + } + + /** + * Assert the response decoded as a Map of the given key and value types. + */ + public MapAssertions asMap(Class keyType, Class valueType) { + ResolvableType type = ResolvableType.forClassWithGenerics(Map.class, keyType, valueType); + Mono> mono = getResponse().body(toMono(type)); + Map map = mono.block(getTimeout()); + return new MapAssertions<>(this.exchangeActions, map, "Response body map"); + } + + + private ClientResponse getResponse() { + return this.exchangeActions.andReturn().getResponse(); + } + + private Duration getTimeout() { + return this.exchangeActions.andReturn().getResponseTimeout(); + } + +} diff --git a/spring-test/src/main/java/org/springframework/test/web/reactive/server/ResponseEntityAssertions.java b/spring-test/src/main/java/org/springframework/test/web/reactive/server/ResponseEntityAssertions.java index 4a1be70ce8..78363daa9e 100644 --- a/spring-test/src/main/java/org/springframework/test/web/reactive/server/ResponseEntityAssertions.java +++ b/spring-test/src/main/java/org/springframework/test/web/reactive/server/ResponseEntityAssertions.java @@ -36,29 +36,27 @@ import static org.springframework.web.reactive.function.BodyExtractors.toMono; */ public class ResponseEntityAssertions extends ObjectAssertions> { - private final ExchangeInfo exchangeInfo; - private final ResolvableType entityType; - ResponseEntityAssertions(ExchangeActions actions, ExchangeInfo info, ResolvableType entityType) { - super(actions, () -> initEntity(info, entityType), "Response body"); - this.exchangeInfo = info; + ResponseEntityAssertions(ExchangeActions actions, ResolvableType entityType) { + super(actions, () -> initEntity(actions, entityType), "Response body"); this.entityType = entityType; } - private static T initEntity(ExchangeInfo exchangeInfo, ResolvableType entityType) { - Mono mono = exchangeInfo.getResponse().body(toMono(entityType)); - return mono.block(exchangeInfo.getResponseTimeout()); + private static T initEntity(ExchangeActions exchangeActions, ResolvableType entityType) { + ExchangeInfo info = exchangeActions.andReturn(); + Mono mono = info.getResponse().body(toMono(entityType)); + return mono.block(info.getResponseTimeout()); } /** - * Assert the response decoded as a Collection of entities of the given type. + * Assert the response decoded as a List of entities of the given type. */ public ListAssertions list() { - Flux flux = this.exchangeInfo.getResponse().body(toFlux(this.entityType)); - List list = flux.collectList().block(this.exchangeInfo.getResponseTimeout()); + Flux flux = getResponse().body(toFlux(this.entityType)); + List list = flux.collectList().block(getTimeout()); return new ListAssertions(getExchangeActions(), list, "Response entity collection"); } @@ -66,7 +64,7 @@ public class ResponseEntityAssertions extends ObjectAssertions stepVerifier() { - Flux flux = this.exchangeInfo.getResponse().body(toFlux(this.entityType)); + Flux flux = getResponse().body(toFlux(this.entityType)); return StepVerifier.create(flux); } diff --git a/spring-test/src/main/java/org/springframework/test/web/reactive/server/ResponseStatusAssertions.java b/spring-test/src/main/java/org/springframework/test/web/reactive/server/ResponseStatusAssertions.java index 387392f493..046476c1af 100644 --- a/spring-test/src/main/java/org/springframework/test/web/reactive/server/ResponseStatusAssertions.java +++ b/spring-test/src/main/java/org/springframework/test/web/reactive/server/ResponseStatusAssertions.java @@ -33,9 +33,9 @@ public class ResponseStatusAssertions { private final HttpStatus httpStatus; - ResponseStatusAssertions(ExchangeActions actions, ExchangeInfo info) { + ResponseStatusAssertions(ExchangeActions actions) { this.exchangeActions = actions; - this.httpStatus = info.getResponse().statusCode(); + this.httpStatus = actions.andReturn().getResponse().statusCode(); } 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 ba7705691a..d56425855c 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 @@ -95,7 +95,7 @@ public class ResponseEntityTests { .exchange(Mono.just(new Person("John")), Person.class) .assertStatus().isCreated() .assertHeader("location").isEqualTo("/persons/John").and() - .assertBodyIsEmpty(); + .assertBody().isEmpty(); }