Browse Source

ExchangeActions update

Put assertBodyXyz options behind a common assertBody() entry point
currently including "isEmpty" and "asMap" but in the future others
related to JSON content or XPath for example.

Now that ExchangeActions provides method to access the ExchangeInfo
it has been removed from constructors of assertion classes that
already have ExchangeActions.
pull/1323/merge
Rossen Stoyanchev 8 years ago
parent
commit
896e4db411
  1. 44
      spring-test/src/main/java/org/springframework/test/web/reactive/server/ExchangeActions.java
  2. 8
      spring-test/src/main/java/org/springframework/test/web/reactive/server/ListAssertions.java
  3. 15
      spring-test/src/main/java/org/springframework/test/web/reactive/server/LoggingExchangeConsumer.java
  4. 10
      spring-test/src/main/java/org/springframework/test/web/reactive/server/ObjectAssertions.java
  5. 74
      spring-test/src/main/java/org/springframework/test/web/reactive/server/ResponseBodyAssertions.java
  6. 22
      spring-test/src/main/java/org/springframework/test/web/reactive/server/ResponseEntityAssertions.java
  7. 4
      spring-test/src/main/java/org/springframework/test/web/reactive/server/ResponseStatusAssertions.java
  8. 2
      spring-test/src/test/java/org/springframework/test/web/reactive/server/samples/ResponseEntityTests.java

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

@ -15,24 +15,16 @@ @@ -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 { @@ -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 { @@ -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 { @@ -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<String> values = headers.getOrDefault(headerName, Collections.emptyList());
return new ResponseHeaderAssertions(this, headerName, values);
}
@ -88,10 +72,8 @@ public final class ExchangeActions { @@ -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 { @@ -107,24 +89,14 @@ public final class ExchangeActions {
* @return further options for asserting response entities
*/
public <T> ResponseEntityAssertions<T> assertEntity(ResolvableType entityType) {
return new ResponseEntityAssertions<T>(this, this.exchangeInfo, entityType);
}
/**
* Assert the response decoded as a Map of the given key and value types.
*/
public <K, V> MapAssertions<K, V> assertBodyAsMap(Class<K> keyType, Class<V> valueType) {
ResolvableType type = ResolvableType.forClassWithGenerics(Map.class, keyType, valueType);
Mono<Map<K, V>> mono = this.exchangeInfo.getResponse().body(toMono(type));
Map<K, V> map = mono.block(this.exchangeInfo.getResponseTimeout());
return new MapAssertions<>(this, map, "Response body map");
return new ResponseEntityAssertions<T>(this, entityType);
}
/**
* Log debug information about the exchange.
*/
public LoggingExchangeConsumer log() {
return new LoggingExchangeConsumer(this, this.exchangeInfo);
return new LoggingExchangeConsumer(this);
}
/**

8
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; @@ -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 <E> the type of element values in the collection
*
@ -38,7 +38,7 @@ public class ListAssertions<E> extends ObjectAssertions<List<E>, ListAssertions< @@ -38,7 +38,7 @@ public class ListAssertions<E> extends ObjectAssertions<List<E>, ListAssertions<
/**
* Assert the size of the collection.
* Assert the size of the list.
*/
public ListAssertions<E> hasSize(int size) {
assertEquals(getErrorPrefix() + " count", size, getValue().size());
@ -46,7 +46,7 @@ public class ListAssertions<E> extends ObjectAssertions<List<E>, ListAssertions< @@ -46,7 +46,7 @@ public class ListAssertions<E> extends ObjectAssertions<List<E>, 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<E> contains(E... entities) {
@ -58,7 +58,7 @@ public class ListAssertions<E> extends ObjectAssertions<List<E>, ListAssertions< @@ -58,7 +58,7 @@ public class ListAssertions<E> extends ObjectAssertions<List<E>, 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<E> doesNotContain(E... entities) {

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

@ -38,12 +38,9 @@ public class LoggingExchangeConsumer { @@ -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 { @@ -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 { @@ -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 { @@ -98,9 +95,13 @@ public class LoggingExchangeConsumer {
private ExchangeActions doLog(Predicate<Log> logLevelPredicate, BiConsumer<Log, String> 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();
}
}

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

@ -15,10 +15,12 @@ @@ -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<V, S extends ObjectAssertions<V, S>> { @@ -113,6 +115,14 @@ public class ObjectAssertions<V, S extends ObjectAssertions<V, S>> {
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;
}

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

@ -0,0 +1,74 @@ @@ -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 <K, V> MapAssertions<K, V> asMap(Class<K> keyType, Class<V> valueType) {
ResolvableType type = ResolvableType.forClassWithGenerics(Map.class, keyType, valueType);
Mono<Map<K, V>> mono = getResponse().body(toMono(type));
Map<K, V> 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();
}
}

22
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; @@ -36,29 +36,27 @@ import static org.springframework.web.reactive.function.BodyExtractors.toMono;
*/
public class ResponseEntityAssertions<T> extends ObjectAssertions<T, ResponseEntityAssertions<T>> {
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> T initEntity(ExchangeInfo exchangeInfo, ResolvableType entityType) {
Mono<T> mono = exchangeInfo.getResponse().body(toMono(entityType));
return mono.block(exchangeInfo.getResponseTimeout());
private static <T> T initEntity(ExchangeActions exchangeActions, ResolvableType entityType) {
ExchangeInfo info = exchangeActions.andReturn();
Mono<T> 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<T> list() {
Flux<T> flux = this.exchangeInfo.getResponse().body(toFlux(this.entityType));
List<T> list = flux.collectList().block(this.exchangeInfo.getResponseTimeout());
Flux<T> flux = getResponse().body(toFlux(this.entityType));
List<T> list = flux.collectList().block(getTimeout());
return new ListAssertions<T>(getExchangeActions(), list, "Response entity collection");
}
@ -66,7 +64,7 @@ public class ResponseEntityAssertions<T> extends ObjectAssertions<T, ResponseEnt @@ -66,7 +64,7 @@ public class ResponseEntityAssertions<T> extends ObjectAssertions<T, ResponseEnt
* Assert the response content using a {@link StepVerifier}.
*/
public StepVerifier.FirstStep<T> stepVerifier() {
Flux<T> flux = this.exchangeInfo.getResponse().body(toFlux(this.entityType));
Flux<T> flux = getResponse().body(toFlux(this.entityType));
return StepVerifier.create(flux);
}

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

@ -33,9 +33,9 @@ public class ResponseStatusAssertions { @@ -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();
}

2
spring-test/src/test/java/org/springframework/test/web/reactive/server/samples/ResponseEntityTests.java

@ -95,7 +95,7 @@ public class ResponseEntityTests { @@ -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();
}

Loading…
Cancel
Save