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:
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user