Refactor WebTestClient response body expectations
Reduce the number of required steps and re-introduce generics support for simple Class<T> cases.
This commit is contained in:
parent
bf3fe93dbd
commit
0e84f246cb
|
|
@ -47,13 +47,13 @@ import org.springframework.web.reactive.function.client.WebClient;
|
|||
import org.springframework.web.server.ServerWebExchange;
|
||||
import org.springframework.web.util.UriBuilder;
|
||||
|
||||
import static java.util.stream.Collectors.toList;
|
||||
import static org.springframework.test.util.AssertionErrors.assertEquals;
|
||||
import static org.springframework.test.util.AssertionErrors.assertTrue;
|
||||
import static org.springframework.web.reactive.function.BodyExtractors.toDataBuffers;
|
||||
import static org.springframework.web.reactive.function.BodyExtractors.toFlux;
|
||||
import static org.springframework.web.reactive.function.BodyExtractors.toMono;
|
||||
|
||||
|
||||
/**
|
||||
* Default implementation of {@link WebTestClient}.
|
||||
*
|
||||
|
|
@ -290,63 +290,57 @@ class DefaultWebTestClient implements WebTestClient {
|
|||
private DefaultResponseSpec toResponseSpec(Mono<ClientResponse> mono) {
|
||||
ClientResponse clientResponse = mono.block(getTimeout());
|
||||
ExchangeResult exchangeResult = wiretapConnector.claimRequest(this.requestId);
|
||||
return new DefaultResponseSpec(exchangeResult, clientResponse);
|
||||
return new DefaultResponseSpec(exchangeResult, clientResponse, getTimeout());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The {@code ExchangeResult} with live, undecoded {@link ClientResponse}.
|
||||
*/
|
||||
private class UndecodedExchangeResult extends ExchangeResult {
|
||||
|
||||
private static class UndecodedExchangeResult extends ExchangeResult {
|
||||
|
||||
private final ClientResponse response;
|
||||
|
||||
private final Duration timeout;
|
||||
|
||||
public UndecodedExchangeResult(ExchangeResult result, ClientResponse response) {
|
||||
|
||||
UndecodedExchangeResult(ExchangeResult result, ClientResponse response, Duration timeout) {
|
||||
super(result);
|
||||
this.response = response;
|
||||
this.timeout = timeout;
|
||||
}
|
||||
|
||||
|
||||
public EntityExchangeResult<?> consumeSingle(ResolvableType elementType) {
|
||||
Object body = this.response.body(toMono(elementType)).block(getTimeout());
|
||||
return new EntityExchangeResult<>(this, body);
|
||||
}
|
||||
|
||||
public EntityExchangeResult<List<?>> consumeList(ResolvableType elementType, int count) {
|
||||
Flux<?> flux = this.response.body(toFlux(elementType));
|
||||
if (count >= 0) {
|
||||
flux = flux.take(count);
|
||||
}
|
||||
List<?> body = flux.collectList().block(getTimeout());
|
||||
return new EntityExchangeResult<>(this, body);
|
||||
}
|
||||
|
||||
public <T> FluxExchangeResult<T> decodeBody(ResolvableType elementType) {
|
||||
Flux<T> body = this.response.body(toFlux(elementType));
|
||||
return new FluxExchangeResult<>(this, body, getTimeout());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public EntityExchangeResult<Map<?, ?>> consumeMap(ResolvableType keyType, ResolvableType valueType) {
|
||||
ResolvableType mapType = ResolvableType.forClassWithGenerics(Map.class, keyType, valueType);
|
||||
return (EntityExchangeResult<Map<?, ?>>) consumeSingle(mapType);
|
||||
public <T> EntityExchangeResult<T> decode(ResolvableType bodyType) {
|
||||
T body = (T) this.response.body(toMono(bodyType)).block(this.timeout);
|
||||
return new EntityExchangeResult<>(this, body);
|
||||
}
|
||||
|
||||
public EntityExchangeResult<Void> consumeEmpty() {
|
||||
DataBuffer buffer = this.response.body(toDataBuffers()).blockFirst(getTimeout());
|
||||
public <T> EntityExchangeResult<List<T>> decodeToList(ResolvableType elementType) {
|
||||
Flux<T> flux = this.response.body(toFlux(elementType));
|
||||
List<T> body = flux.collectList().block(this.timeout);
|
||||
return new EntityExchangeResult<>(this, body);
|
||||
}
|
||||
|
||||
public <T> FluxExchangeResult<T> decodeToFlux(ResolvableType elementType) {
|
||||
Flux<T> body = this.response.body(toFlux(elementType));
|
||||
return new FluxExchangeResult<>(this, body, this.timeout);
|
||||
}
|
||||
|
||||
public EntityExchangeResult<Void> decodeToEmpty() {
|
||||
DataBuffer buffer = this.response.body(toDataBuffers()).blockFirst(this.timeout);
|
||||
assertWithDiagnostics(() -> assertTrue("Expected empty body", buffer == null));
|
||||
return new EntityExchangeResult<>(this, null);
|
||||
}
|
||||
}
|
||||
|
||||
private class DefaultResponseSpec implements ResponseSpec {
|
||||
|
||||
private static class DefaultResponseSpec implements ResponseSpec {
|
||||
|
||||
private final UndecodedExchangeResult result;
|
||||
|
||||
|
||||
public DefaultResponseSpec(ExchangeResult result, ClientResponse response) {
|
||||
this.result = new UndecodedExchangeResult(result, response);
|
||||
DefaultResponseSpec(ExchangeResult result, ClientResponse response, Duration timeout) {
|
||||
this.result = new UndecodedExchangeResult(result, response, timeout);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -360,210 +354,133 @@ class DefaultWebTestClient implements WebTestClient {
|
|||
}
|
||||
|
||||
@Override
|
||||
public TypeBodySpec expectBody(Class<?> elementType) {
|
||||
return expectBody(ResolvableType.forClass(elementType));
|
||||
public <B> BodySpec<B, ?> expectBody(Class<B> bodyType) {
|
||||
return expectBody(ResolvableType.forClass(bodyType));
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeBodySpec expectBody(ResolvableType elementType) {
|
||||
return new DefaultTypeBodySpec(this.result, elementType);
|
||||
public <B> BodySpec<B, ?> expectBody(ResolvableType bodyType) {
|
||||
return new DefaultBodySpec<>(this.result.decode(bodyType));
|
||||
}
|
||||
|
||||
@Override
|
||||
public BodySpec expectBody() {
|
||||
return new DefaultBodySpec(this.result);
|
||||
public <E> ListBodySpec<E> expectBodyList(Class<E> elementType) {
|
||||
return expectBodyList(ResolvableType.forClass(elementType));
|
||||
}
|
||||
|
||||
@Override
|
||||
public <E> ListBodySpec<E> expectBodyList(ResolvableType elementType) {
|
||||
return new DefaultListBodySpec<>(this.result.decodeToList(elementType));
|
||||
}
|
||||
|
||||
@Override
|
||||
public BodyContentSpec expectBody() {
|
||||
return new DefaultBodyContentSpec(this.result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> FluxExchangeResult<T> returnResult(Class<T> elementType) {
|
||||
return returnResult(ResolvableType.forClass(elementType));
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> FluxExchangeResult<T> returnResult(ResolvableType elementType) {
|
||||
return this.result.decodeToFlux(elementType);
|
||||
}
|
||||
}
|
||||
|
||||
private class DefaultTypeBodySpec implements TypeBodySpec {
|
||||
|
||||
private static class DefaultBodySpec<B, S extends BodySpec<B, S>> implements BodySpec<B, S> {
|
||||
|
||||
private final EntityExchangeResult<B> result;
|
||||
|
||||
|
||||
DefaultBodySpec(EntityExchangeResult<B> result) {
|
||||
this.result = result;
|
||||
}
|
||||
|
||||
|
||||
protected EntityExchangeResult<B> getResult() {
|
||||
return this.result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends S> T isEqualTo(B expected) {
|
||||
Object actual = this.result.getResponseBody();
|
||||
this.result.assertWithDiagnostics(() -> assertEquals("Response body", expected, actual));
|
||||
return self();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private <T extends S> T self() {
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityExchangeResult<B> returnResult() {
|
||||
return this.result;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static class DefaultListBodySpec<E> extends DefaultBodySpec<List<E>, ListBodySpec<E>>
|
||||
implements ListBodySpec<E> {
|
||||
|
||||
|
||||
DefaultListBodySpec(EntityExchangeResult<List<E>> result) {
|
||||
super(result);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ListBodySpec<E> hasSize(int size) {
|
||||
List<E> actual = getResult().getResponseBody();
|
||||
String message = "Response body does not contain " + size + " elements";
|
||||
getResult().assertWithDiagnostics(() -> assertEquals(message, size, actual.size()));
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public ListBodySpec<E> contains(E... elements) {
|
||||
List<E> expected = Arrays.asList(elements);
|
||||
List<E> actual = getResult().getResponseBody();
|
||||
String message = "Response body does not contain " + expected;
|
||||
getResult().assertWithDiagnostics(() -> assertTrue(message, actual.containsAll(expected)));
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public ListBodySpec<E> doesNotContain(E... elements) {
|
||||
List<E> expected = Arrays.asList(elements);
|
||||
List<E> actual = getResult().getResponseBody();
|
||||
String message = "Response body should have contained " + expected;
|
||||
getResult().assertWithDiagnostics(() -> assertTrue(message, !actual.containsAll(expected)));
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public EntityExchangeResult<List<E>> returnResult() {
|
||||
return getResult();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static class DefaultBodyContentSpec implements BodyContentSpec {
|
||||
|
||||
private final UndecodedExchangeResult result;
|
||||
|
||||
private final ResolvableType elementType;
|
||||
|
||||
|
||||
public DefaultTypeBodySpec(UndecodedExchangeResult result, ResolvableType elementType) {
|
||||
DefaultBodyContentSpec(UndecodedExchangeResult result) {
|
||||
this.result = result;
|
||||
this.elementType = elementType;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public SingleValueBodySpec value() {
|
||||
return new DefaultSingleValueBodySpec(this.result.consumeSingle(this.elementType));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListBodySpec list() {
|
||||
return list(-1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListBodySpec list(int count) {
|
||||
return new DefaultListBodySpec(this.result.consumeList(this.elementType, count));
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> FluxExchangeResult<T> returnResult() {
|
||||
return this.result.decodeBody(this.elementType);
|
||||
}
|
||||
}
|
||||
|
||||
private class DefaultSingleValueBodySpec implements SingleValueBodySpec {
|
||||
|
||||
private final EntityExchangeResult<?> result;
|
||||
|
||||
|
||||
public DefaultSingleValueBodySpec(EntityExchangeResult<?> result) {
|
||||
this.result = result;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public <T> EntityExchangeResult<T> isEqualTo(T expected) {
|
||||
Object actual = this.result.getResponseBody();
|
||||
this.result.assertWithDiagnostics(() -> assertEquals("Response body", expected, actual));
|
||||
return returnResult();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public <T> EntityExchangeResult<T> returnResult() {
|
||||
return new EntityExchangeResult<>(this.result, (T) this.result.getResponseBody());
|
||||
}
|
||||
}
|
||||
|
||||
private class DefaultListBodySpec implements ListBodySpec {
|
||||
|
||||
private final EntityExchangeResult<List<?>> result;
|
||||
|
||||
|
||||
public DefaultListBodySpec(EntityExchangeResult<List<?>> result) {
|
||||
this.result = result;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public <T> EntityExchangeResult<List<T>> isEqualTo(List<T> expected) {
|
||||
List<?> actual = this.result.getResponseBody();
|
||||
this.result.assertWithDiagnostics(() -> assertEquals("Response body", expected, actual));
|
||||
return returnResult();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListBodySpec hasSize(int size) {
|
||||
List<?> actual = this.result.getResponseBody();
|
||||
String message = "Response body does not contain " + size + " elements";
|
||||
this.result.assertWithDiagnostics(() -> assertEquals(message, size, actual.size()));
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListBodySpec contains(Object... elements) {
|
||||
List<?> expected = Arrays.asList(elements);
|
||||
List<?> actual = this.result.getResponseBody();
|
||||
String message = "Response body does not contain " + expected;
|
||||
this.result.assertWithDiagnostics(() -> assertTrue(message, actual.containsAll(expected)));
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListBodySpec doesNotContain(Object... elements) {
|
||||
List<?> expected = Arrays.asList(elements);
|
||||
List<?> actual = this.result.getResponseBody();
|
||||
String message = "Response body should have contained " + expected;
|
||||
this.result.assertWithDiagnostics(() -> assertTrue(message, !actual.containsAll(expected)));
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> EntityExchangeResult<List<T>> returnResult() {
|
||||
return new EntityExchangeResult<>(this.result, (List<T>) this.result.getResponseBody());
|
||||
}
|
||||
}
|
||||
|
||||
private class DefaultBodySpec implements BodySpec {
|
||||
|
||||
private final UndecodedExchangeResult exchangeResult;
|
||||
|
||||
|
||||
public DefaultBodySpec(UndecodedExchangeResult result) {
|
||||
this.exchangeResult = result;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public EntityExchangeResult<Void> isEmpty() {
|
||||
return this.exchangeResult.consumeEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public MapBodySpec map(Class<?> keyType, Class<?> valueType) {
|
||||
return map(ResolvableType.forClass(keyType), ResolvableType.forClass(valueType));
|
||||
}
|
||||
|
||||
@Override
|
||||
public MapBodySpec map(ResolvableType keyType, ResolvableType valueType) {
|
||||
return new DefaultMapBodySpec(this.exchangeResult.consumeMap(keyType, valueType));
|
||||
}
|
||||
}
|
||||
|
||||
private class DefaultMapBodySpec implements MapBodySpec {
|
||||
|
||||
private final EntityExchangeResult<Map<?, ?>> result;
|
||||
|
||||
|
||||
public DefaultMapBodySpec(EntityExchangeResult<Map<?, ?>> result) {
|
||||
this.result = result;
|
||||
}
|
||||
|
||||
|
||||
private Map<?, ?> getBody() {
|
||||
return this.result.getResponseBody();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <K, V> EntityExchangeResult<Map<K, V>> isEqualTo(Map<K, V> expected) {
|
||||
String message = "Response body map";
|
||||
this.result.assertWithDiagnostics(() -> assertEquals(message, expected, getBody()));
|
||||
return returnResult();
|
||||
}
|
||||
|
||||
@Override
|
||||
public MapBodySpec hasSize(int size) {
|
||||
String message = "Response body map size";
|
||||
this.result.assertWithDiagnostics(() -> assertEquals(message, size, getBody().size()));
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MapBodySpec contains(Object key, Object value) {
|
||||
String message = "Response body map value for key " + key;
|
||||
this.result.assertWithDiagnostics(() -> assertEquals(message, value, getBody().get(key)));
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MapBodySpec containsKeys(Object... keys) {
|
||||
List<?> missing = Arrays.stream(keys).filter(k -> !getBody().containsKey(k)).collect(toList());
|
||||
String message = "Response body map does not contain keys " + missing;
|
||||
this.result.assertWithDiagnostics(() -> assertTrue(message, missing.isEmpty()));
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MapBodySpec containsValues(Object... values) {
|
||||
List<?> missing = Arrays.stream(values).filter(v -> !getBody().containsValue(v)).collect(toList());
|
||||
String message = "Response body map does not contain values " + missing;
|
||||
this.result.assertWithDiagnostics(() -> assertTrue(message, missing.isEmpty()));
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <K, V> EntityExchangeResult<Map<K, V>> returnResult() {
|
||||
return new EntityExchangeResult<>(this.result, (Map<K, V>) getBody());
|
||||
return this.result.decodeToEmpty();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -491,177 +491,110 @@ public interface WebTestClient {
|
|||
interface ResponseSpec {
|
||||
|
||||
/**
|
||||
* Assertions on the response status.
|
||||
* Declare expectations on the response status.
|
||||
*/
|
||||
StatusAssertions expectStatus();
|
||||
|
||||
/**
|
||||
* Assertions on the headers of the response.
|
||||
* Declared expectations on the headers of the response.
|
||||
*/
|
||||
HeaderAssertions expectHeader();
|
||||
|
||||
/**
|
||||
* Assertions on the body of the response extracted to one or more
|
||||
* representations of the given type.
|
||||
* Declare expectations on the response body decoded to {@code <B>}.
|
||||
* @param bodyType the expected body type
|
||||
*/
|
||||
TypeBodySpec expectBody(Class<?> elementType);
|
||||
<B> BodySpec<B, ?> expectBody(Class<B> bodyType);
|
||||
|
||||
/**
|
||||
* Variant of {@link #expectBody(Class)} for use with generic types.
|
||||
* Variant of {@link #expectBody(Class)} for a body type with generics.
|
||||
*/
|
||||
TypeBodySpec expectBody(ResolvableType elementType);
|
||||
<B> BodySpec<B, ?> expectBody(ResolvableType bodyType);
|
||||
|
||||
/**
|
||||
* Other assertions on the response body -- isEmpty, map, etc.
|
||||
* Declare expectations on the response body decoded to {@code List<E>}.
|
||||
* @param elementType the expected List element type
|
||||
*/
|
||||
BodySpec expectBody();
|
||||
<E> ListBodySpec<E> expectBodyList(Class<E> elementType);
|
||||
|
||||
/**
|
||||
* Variant of {@link #expectBodyList(Class)} for element types with generics.
|
||||
*/
|
||||
<E> ListBodySpec<E> expectBodyList(ResolvableType elementType);
|
||||
|
||||
/**
|
||||
* Declare expectations on the response body content.
|
||||
*/
|
||||
BodyContentSpec expectBody();
|
||||
|
||||
/**
|
||||
* Return the exchange result with the body decoded to {@code Flux<T>}.
|
||||
* Use this option for infinite streams and consume the stream with
|
||||
* the {@code StepVerifier} from the Reactor Add-Ons.
|
||||
*
|
||||
* @see <a href="https://github.com/reactor/reactor-addons">
|
||||
* https://github.com/reactor/reactor-addons</a>
|
||||
*/
|
||||
<T> FluxExchangeResult<T> returnResult(Class<T> elementType);
|
||||
|
||||
/**
|
||||
* Variant of {@link #returnResult(Class)} for element types with generics.
|
||||
*/
|
||||
<T> FluxExchangeResult<T> returnResult(ResolvableType elementType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Specification for extracting entities from the response body.
|
||||
* Specification for asserting a response body decoded to a single Object.
|
||||
*/
|
||||
interface TypeBodySpec {
|
||||
|
||||
/**
|
||||
* Extract a single representations from the response.
|
||||
*/
|
||||
SingleValueBodySpec value();
|
||||
|
||||
/**
|
||||
* Extract a list of representations from the response.
|
||||
*/
|
||||
ListBodySpec list();
|
||||
|
||||
/**
|
||||
* Extract a list of representations consuming the first N elements.
|
||||
*/
|
||||
ListBodySpec list(int elementCount);
|
||||
|
||||
/**
|
||||
* Return request and response details for the exchange incluidng the
|
||||
* response body decoded as {@code Flux<T>} where {@code <T>} is the
|
||||
* expected element type. The returned {@code Flux} may for example be
|
||||
* verified with the Reactor {@code StepVerifier}.
|
||||
*/
|
||||
<T> FluxExchangeResult<T> returnResult();
|
||||
}
|
||||
|
||||
/**
|
||||
* Specification to assert a single value extracted from the response body.
|
||||
*/
|
||||
interface SingleValueBodySpec {
|
||||
interface BodySpec<B, S extends BodySpec<B, S>> {
|
||||
|
||||
/**
|
||||
* Assert the extracted body is equal to the given value.
|
||||
*/
|
||||
<T> EntityExchangeResult<T> isEqualTo(T expected);
|
||||
<T extends S> T isEqualTo(B expected);
|
||||
|
||||
/**
|
||||
* Return request and response details for the exchange including the
|
||||
* extracted response body.
|
||||
* Return the exchange result with the decoded body.
|
||||
*/
|
||||
<T> EntityExchangeResult<T> returnResult();
|
||||
EntityExchangeResult<B> returnResult();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Specification to assert a list of values extracted from the response.
|
||||
* Specification for asserting a response body decoded to a List.
|
||||
*/
|
||||
interface ListBodySpec {
|
||||
|
||||
/**
|
||||
* Assert the extracted body is equal to the given list.
|
||||
*/
|
||||
<T> EntityExchangeResult<List<T>> isEqualTo(List<T> expected);
|
||||
interface ListBodySpec<E> extends BodySpec<List<E>, ListBodySpec<E>> {
|
||||
|
||||
/**
|
||||
* Assert the extracted list of values is of the given size.
|
||||
* @param size the expected size
|
||||
*/
|
||||
ListBodySpec hasSize(int size);
|
||||
ListBodySpec<E> hasSize(int size);
|
||||
|
||||
/**
|
||||
* Assert the extracted list of values contains the given elements.
|
||||
* @param elements the elements to check
|
||||
*/
|
||||
ListBodySpec contains(Object... elements);
|
||||
@SuppressWarnings("unchecked")
|
||||
ListBodySpec<E> contains(E... elements);
|
||||
|
||||
/**
|
||||
* Assert the extracted list of values doesn't contain the given elements.
|
||||
* @param elements the elements to check
|
||||
*/
|
||||
ListBodySpec doesNotContain(Object... elements);
|
||||
@SuppressWarnings("unchecked")
|
||||
ListBodySpec<E> doesNotContain(E... elements);
|
||||
|
||||
/**
|
||||
* Return request and response details for the exchange including the
|
||||
* extracted response body.
|
||||
*/
|
||||
<T> EntityExchangeResult<List<T>> returnResult();
|
||||
}
|
||||
|
||||
/**
|
||||
* Specification to apply additional assertions on the response body.
|
||||
*/
|
||||
interface BodySpec {
|
||||
interface BodyContentSpec {
|
||||
|
||||
/**
|
||||
* Consume the body and verify it is empty.
|
||||
* @return request and response details from the exchange
|
||||
* @return the exchange result
|
||||
*/
|
||||
EntityExchangeResult<Void> isEmpty();
|
||||
|
||||
/**
|
||||
* Extract the response body as a Map with the given key and value type.
|
||||
*/
|
||||
MapBodySpec map(Class<?> keyType, Class<?> valueType);
|
||||
|
||||
/**
|
||||
* Variant of {@link #map(Class, Class)} for use with generic types.
|
||||
*/
|
||||
MapBodySpec map(ResolvableType keyType, ResolvableType valueType);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Specification to assert response the body extracted as a map.
|
||||
*/
|
||||
interface MapBodySpec {
|
||||
|
||||
/**
|
||||
* Assert the extracted map is equal to the given list of elements.
|
||||
*/
|
||||
<K, V> EntityExchangeResult<Map<K, V>> isEqualTo(Map<K, V> expected);
|
||||
|
||||
/**
|
||||
* Assert the extracted map has the given size.
|
||||
* @param size the expected size
|
||||
*/
|
||||
MapBodySpec hasSize(int size);
|
||||
|
||||
/**
|
||||
* Assert the extracted map contains the given key value pair.
|
||||
* @param key the key to check
|
||||
* @param value the value to check
|
||||
*/
|
||||
MapBodySpec contains(Object key, Object value);
|
||||
|
||||
/**
|
||||
* Assert the extracted map contains the given keys.
|
||||
* @param keys the keys to check
|
||||
*/
|
||||
MapBodySpec containsKeys(Object... keys);
|
||||
|
||||
/**
|
||||
* Assert the extracted map contains the given values.
|
||||
* @param values the keys to check
|
||||
*/
|
||||
MapBodySpec containsValues(Object... values);
|
||||
|
||||
/**
|
||||
* Return request and response details for the exchange including the
|
||||
* extracted response body.
|
||||
*/
|
||||
<K, V> EntityExchangeResult<Map<K, V>> returnResult();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ public class DefaultControllerSpecTests {
|
|||
.get().uri("/")
|
||||
.exchange()
|
||||
.expectStatus().isOk()
|
||||
.expectBody(String.class).value().isEqualTo("Success");
|
||||
.expectBody(String.class).isEqualTo("Success");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -49,7 +49,7 @@ public class DefaultControllerSpecTests {
|
|||
.get().uri("/exception")
|
||||
.exchange()
|
||||
.expectStatus().isBadRequest()
|
||||
.expectBody(String.class).value().isEqualTo("Handled exception");
|
||||
.expectBody(String.class).isEqualTo("Handled exception");
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -40,9 +40,10 @@ import org.springframework.web.bind.annotation.RequestBody;
|
|||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import static java.time.Duration.*;
|
||||
import static java.time.Duration.ofMillis;
|
||||
import static org.hamcrest.CoreMatchers.endsWith;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.springframework.core.ResolvableType.forClassWithGenerics;
|
||||
import static org.springframework.http.MediaType.TEXT_EVENT_STREAM;
|
||||
|
||||
/**
|
||||
|
|
@ -62,7 +63,7 @@ public class ResponseEntityTests {
|
|||
.exchange()
|
||||
.expectStatus().isOk()
|
||||
.expectHeader().contentType(MediaType.APPLICATION_JSON_UTF8)
|
||||
.expectBody(Person.class).value().isEqualTo(new Person("John"));
|
||||
.expectBody(Person.class).isEqualTo(new Person("John"));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -75,7 +76,7 @@ public class ResponseEntityTests {
|
|||
.exchange()
|
||||
.expectStatus().isOk()
|
||||
.expectHeader().contentType(MediaType.APPLICATION_JSON_UTF8)
|
||||
.expectBody(Person.class).list().isEqualTo(expected);
|
||||
.expectBodyList(Person.class).isEqualTo(expected);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -89,8 +90,7 @@ public class ResponseEntityTests {
|
|||
this.client.get().uri("/persons?map=true")
|
||||
.exchange()
|
||||
.expectStatus().isOk()
|
||||
.expectBody()
|
||||
.map(String.class, Person.class).isEqualTo(map);
|
||||
.expectBody(forClassWithGenerics(Map.class, String.class, Person.class)).isEqualTo(map);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -102,8 +102,7 @@ public class ResponseEntityTests {
|
|||
.exchange()
|
||||
.expectStatus().isOk()
|
||||
.expectHeader().contentType(TEXT_EVENT_STREAM)
|
||||
.expectBody(Person.class)
|
||||
.returnResult();
|
||||
.returnResult(Person.class);
|
||||
|
||||
StepVerifier.create(result.getResponseBody())
|
||||
.expectNext(new Person("N0"), new Person("N1"), new Person("N2"))
|
||||
|
|
@ -126,6 +125,7 @@ public class ResponseEntityTests {
|
|||
|
||||
@RestController
|
||||
@RequestMapping("/persons")
|
||||
@SuppressWarnings("unused")
|
||||
static class PersonController {
|
||||
|
||||
@GetMapping("/{name}")
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ public class ApplicationContextTests {
|
|||
this.client.get().uri("/principal")
|
||||
.exchange()
|
||||
.expectStatus().isOk()
|
||||
.expectBody(String.class).value().isEqualTo("Hello Mr. Pablo!");
|
||||
.expectBody(String.class).isEqualTo("Hello Mr. Pablo!");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -72,7 +72,7 @@ public class ApplicationContextTests {
|
|||
.get().uri("/principal")
|
||||
.exchange()
|
||||
.expectStatus().isOk()
|
||||
.expectBody(String.class).value().isEqualTo("Hello Mr. Giovanni!");
|
||||
.expectBody(String.class).isEqualTo("Hello Mr. Giovanni!");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -83,7 +83,7 @@ public class ApplicationContextTests {
|
|||
.get().uri("/attributes")
|
||||
.exchange()
|
||||
.expectStatus().isOk()
|
||||
.expectBody(String.class).value().isEqualTo("foo+bar");
|
||||
.expectBody(String.class).isEqualTo("foo+bar");
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ public class ControllerTests {
|
|||
this.client.get().uri("/principal")
|
||||
.exchange()
|
||||
.expectStatus().isOk()
|
||||
.expectBody(String.class).value().isEqualTo("Hello Mr. Pablo!");
|
||||
.expectBody(String.class).isEqualTo("Hello Mr. Pablo!");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -57,7 +57,7 @@ public class ControllerTests {
|
|||
.get().uri("/principal")
|
||||
.exchange()
|
||||
.expectStatus().isOk()
|
||||
.expectBody(String.class).value().isEqualTo("Hello Mr. Giovanni!");
|
||||
.expectBody(String.class).isEqualTo("Hello Mr. Giovanni!");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -68,7 +68,7 @@ public class ControllerTests {
|
|||
.get().uri("/attributes")
|
||||
.exchange()
|
||||
.expectStatus().isOk()
|
||||
.expectBody(String.class).value().isEqualTo("foo+bar");
|
||||
.expectBody(String.class).isEqualTo("foo+bar");
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ public class HttpServerTests {
|
|||
this.client.get().uri("/test")
|
||||
.exchange()
|
||||
.expectStatus().isOk()
|
||||
.expectBody(String.class).value().isEqualTo("It works!");
|
||||
.expectBody(String.class).isEqualTo("It works!");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ public class RouterFunctionTests {
|
|||
this.testClient.get().uri("/test")
|
||||
.exchange()
|
||||
.expectStatus().isOk()
|
||||
.expectBody(String.class).value().isEqualTo("It works!");
|
||||
.expectBody(String.class).isEqualTo("It works!");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue