mirror of
https://github.com/spring-projects/spring-framework
synced 2026-06-08 17:33:33 +00:00
Align RestTestClient and WebTestClient structure
See gh-34428
This commit is contained in:
+12
-12
@@ -261,18 +261,6 @@ class DefaultWebTestClient implements WebTestClient {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RequestBodySpec attribute(String name, Object value) {
|
||||
this.attributes.put(name, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RequestBodySpec attributes(Consumer<Map<String, Object>> attributesConsumer) {
|
||||
attributesConsumer.accept(this.attributes);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RequestBodySpec accept(MediaType... acceptableMediaTypes) {
|
||||
getHeaders().setAccept(Arrays.asList(acceptableMediaTypes));
|
||||
@@ -321,6 +309,18 @@ class DefaultWebTestClient implements WebTestClient {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RequestBodySpec attribute(String name, Object value) {
|
||||
this.attributes.put(name, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RequestBodySpec attributes(Consumer<Map<String, Object>> attributesConsumer) {
|
||||
attributesConsumer.accept(this.attributes);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RequestBodySpec apiVersion(Object version) {
|
||||
this.apiVersion = version;
|
||||
|
||||
+1
-2
@@ -820,6 +820,7 @@ public interface WebTestClient {
|
||||
interface RequestHeadersUriSpec<S extends RequestHeadersSpec<S>> extends UriSpec<S>, RequestHeadersSpec<S> {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Specification for providing the body and the URI of a request.
|
||||
*/
|
||||
@@ -932,7 +933,6 @@ public interface WebTestClient {
|
||||
@FunctionalInterface
|
||||
interface ResponseSpecConsumer extends Consumer<ResponseSpec> {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1014,7 +1014,6 @@ public interface WebTestClient {
|
||||
* Spec for expectations on the response body content.
|
||||
*/
|
||||
interface BodyContentSpec {
|
||||
|
||||
/**
|
||||
* Assert the response body is empty and return the exchange result.
|
||||
*/
|
||||
|
||||
+1
@@ -24,6 +24,7 @@ import org.springframework.util.MultiValueMap;
|
||||
* Assertions on cookies of the response.
|
||||
*
|
||||
* @author Rob Worsnop
|
||||
* @since 7.0
|
||||
*/
|
||||
public class CookieAssertions extends AbstractCookieAssertions<ExchangeResult, RestTestClient.ResponseSpec> {
|
||||
|
||||
|
||||
+113
-98
@@ -50,6 +50,8 @@ import org.springframework.web.util.UriBuilder;
|
||||
* Default implementation of {@link RestTestClient}.
|
||||
*
|
||||
* @author Rob Worsnop
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 7.0
|
||||
*/
|
||||
class DefaultRestTestClient implements RestTestClient {
|
||||
|
||||
@@ -59,11 +61,13 @@ class DefaultRestTestClient implements RestTestClient {
|
||||
|
||||
private final RestClient.Builder restClientBuilder;
|
||||
|
||||
|
||||
DefaultRestTestClient(RestClient.Builder restClientBuilder) {
|
||||
this.restClient = restClientBuilder.build();
|
||||
this.restClientBuilder = restClientBuilder;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public RequestHeadersUriSpec<?> get() {
|
||||
return methodInternal(HttpMethod.GET);
|
||||
@@ -104,41 +108,30 @@ class DefaultRestTestClient implements RestTestClient {
|
||||
return methodInternal(method);
|
||||
}
|
||||
|
||||
private RequestBodyUriSpec methodInternal(HttpMethod httpMethod) {
|
||||
return new DefaultRequestBodyUriSpec(this.restClient.method(httpMethod));
|
||||
}
|
||||
|
||||
@Override
|
||||
public <B extends Builder<B>> Builder<B> mutate() {
|
||||
return new DefaultRestTestClientBuilder<>(this.restClientBuilder);
|
||||
}
|
||||
|
||||
private RequestBodyUriSpec methodInternal(HttpMethod httpMethod) {
|
||||
return new DefaultRequestBodyUriSpec(this.restClient.method(httpMethod));
|
||||
}
|
||||
|
||||
|
||||
private class DefaultRequestBodyUriSpec implements RequestBodyUriSpec {
|
||||
|
||||
private final RestClient.RequestBodyUriSpec requestHeadersUriSpec;
|
||||
|
||||
private RestClient.RequestBodySpec requestBodySpec;
|
||||
|
||||
private final String requestId;
|
||||
|
||||
|
||||
public DefaultRequestBodyUriSpec(RestClient.RequestBodyUriSpec spec) {
|
||||
DefaultRequestBodyUriSpec(RestClient.RequestBodyUriSpec spec) {
|
||||
this.requestHeadersUriSpec = spec;
|
||||
this.requestBodySpec = spec;
|
||||
this.requestId = String.valueOf(requestIndex.incrementAndGet());
|
||||
}
|
||||
|
||||
@Override
|
||||
public RequestBodySpec accept(MediaType... acceptableMediaTypes) {
|
||||
this.requestBodySpec = this.requestHeadersUriSpec.accept(acceptableMediaTypes);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RequestBodySpec uri(URI uri) {
|
||||
this.requestBodySpec = this.requestHeadersUriSpec.uri(uri);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RequestBodySpec uri(String uriTemplate, Object... uriVariables) {
|
||||
this.requestBodySpec = this.requestHeadersUriSpec.uri(uriTemplate, uriVariables);
|
||||
@@ -158,14 +151,8 @@ class DefaultRestTestClient implements RestTestClient {
|
||||
}
|
||||
|
||||
@Override
|
||||
public RequestBodySpec cookie(String name, String value) {
|
||||
this.requestBodySpec = this.requestHeadersUriSpec.cookie(name, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RequestBodySpec cookies(Consumer<MultiValueMap<String, String>> cookiesConsumer) {
|
||||
this.requestBodySpec = this.requestHeadersUriSpec.cookies(cookiesConsumer);
|
||||
public RequestBodySpec uri(URI uri) {
|
||||
this.requestBodySpec = this.requestHeadersUriSpec.uri(uri);
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -176,14 +163,14 @@ class DefaultRestTestClient implements RestTestClient {
|
||||
}
|
||||
|
||||
@Override
|
||||
public RequestBodySpec contentType(MediaType contentType) {
|
||||
this.requestBodySpec = this.requestHeadersUriSpec.contentType(contentType);
|
||||
public RequestBodySpec headers(Consumer<HttpHeaders> headersConsumer) {
|
||||
this.requestBodySpec = this.requestHeadersUriSpec.headers(headersConsumer);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RequestHeadersSpec<?> body(Object body) {
|
||||
this.requestHeadersUriSpec.body(body);
|
||||
public RequestBodySpec accept(MediaType... acceptableMediaTypes) {
|
||||
this.requestBodySpec = this.requestHeadersUriSpec.accept(acceptableMediaTypes);
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -193,6 +180,24 @@ class DefaultRestTestClient implements RestTestClient {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RequestBodySpec contentType(MediaType contentType) {
|
||||
this.requestBodySpec = this.requestHeadersUriSpec.contentType(contentType);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RequestBodySpec cookie(String name, String value) {
|
||||
this.requestBodySpec = this.requestHeadersUriSpec.cookie(name, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RequestBodySpec cookies(Consumer<MultiValueMap<String, String>> cookiesConsumer) {
|
||||
this.requestBodySpec = this.requestHeadersUriSpec.cookies(cookiesConsumer);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RequestBodySpec ifModifiedSince(ZonedDateTime ifModifiedSince) {
|
||||
this.requestBodySpec = this.requestHeadersUriSpec.ifModifiedSince(ifModifiedSince);
|
||||
@@ -205,12 +210,6 @@ class DefaultRestTestClient implements RestTestClient {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RequestBodySpec headers(Consumer<HttpHeaders> headersConsumer) {
|
||||
this.requestBodySpec = this.requestHeadersUriSpec.headers(headersConsumer);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RequestBodySpec attribute(String name, Object value) {
|
||||
this.requestBodySpec = this.requestHeadersUriSpec.attribute(name, value);
|
||||
@@ -223,6 +222,12 @@ class DefaultRestTestClient implements RestTestClient {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RequestHeadersSpec<?> body(Object body) {
|
||||
this.requestHeadersUriSpec.body(body);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResponseSpec exchange() {
|
||||
this.requestBodySpec = this.requestBodySpec.header(RESTTESTCLIENT_REQUEST_ID, this.requestId);
|
||||
@@ -233,11 +238,12 @@ class DefaultRestTestClient implements RestTestClient {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static class DefaultResponseSpec implements ResponseSpec {
|
||||
|
||||
private final ExchangeResult exchangeResult;
|
||||
|
||||
public DefaultResponseSpec(ExchangeResult exchangeResult) {
|
||||
DefaultResponseSpec(ExchangeResult exchangeResult) {
|
||||
this.exchangeResult = exchangeResult;
|
||||
}
|
||||
|
||||
@@ -247,9 +253,13 @@ class DefaultRestTestClient implements RestTestClient {
|
||||
}
|
||||
|
||||
@Override
|
||||
public BodyContentSpec expectBody() {
|
||||
byte[] body = this.exchangeResult.getBody(byte[].class);
|
||||
return new DefaultBodyContentSpec( new EntityExchangeResult<>(this.exchangeResult, body));
|
||||
public HeaderAssertions expectHeader() {
|
||||
return new HeaderAssertions(this.exchangeResult, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CookieAssertions expectCookie() {
|
||||
return new CookieAssertions(this.exchangeResult, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -265,13 +275,19 @@ class DefaultRestTestClient implements RestTestClient {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CookieAssertions expectCookie() {
|
||||
return new CookieAssertions(this.exchangeResult, this);
|
||||
public BodyContentSpec expectBody() {
|
||||
byte[] body = this.exchangeResult.getBody(byte[].class);
|
||||
return new DefaultBodyContentSpec( new EntityExchangeResult<>(this.exchangeResult, body));
|
||||
}
|
||||
|
||||
@Override
|
||||
public HeaderAssertions expectHeader() {
|
||||
return new HeaderAssertions(this.exchangeResult, this);
|
||||
public <T> EntityExchangeResult<T> returnResult(Class<T> elementClass) {
|
||||
return new EntityExchangeResult<>(this.exchangeResult, this.exchangeResult.getBody(elementClass));
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> EntityExchangeResult<T> returnResult(ParameterizedTypeReference<T> elementTypeRef) {
|
||||
return new EntityExchangeResult<>(this.exchangeResult, this.exchangeResult.getBody(elementTypeRef));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -295,22 +311,63 @@ class DefaultRestTestClient implements RestTestClient {
|
||||
}
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> EntityExchangeResult<T> returnResult(Class<T> elementClass) {
|
||||
return new EntityExchangeResult<>(this.exchangeResult, this.exchangeResult.getBody(elementClass));
|
||||
|
||||
private static class DefaultBodySpec<B, S extends BodySpec<B, S>> implements BodySpec<B, S> {
|
||||
|
||||
private final EntityExchangeResult<B> result;
|
||||
|
||||
DefaultBodySpec(@Nullable EntityExchangeResult<B> result) {
|
||||
this.result = Objects.requireNonNull(result, "exchangeResult must be non-null");
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> EntityExchangeResult<T> returnResult(ParameterizedTypeReference<T> elementTypeRef) {
|
||||
return new EntityExchangeResult<>(this.exchangeResult, this.exchangeResult.getBody(elementTypeRef));
|
||||
public <T extends S> T isEqualTo(B expected) {
|
||||
this.result.assertWithDiagnostics(() ->
|
||||
AssertionErrors.assertEquals("Response body", expected, this.result.getResponseBody()));
|
||||
return self();
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("NullAway") // https://github.com/uber/NullAway/issues/1129
|
||||
public <T extends S, R> T value(Function<B, R> bodyMapper, Matcher<? super R> matcher) {
|
||||
this.result.assertWithDiagnostics(() -> {
|
||||
B body = this.result.getResponseBody();
|
||||
MatcherAssert.assertThat(bodyMapper.apply(body), matcher);
|
||||
});
|
||||
return self();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends S> T value(Consumer<B> consumer) {
|
||||
this.result.assertWithDiagnostics(() -> consumer.accept(this.result.getResponseBody()));
|
||||
return self();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends S> T consumeWith(Consumer<EntityExchangeResult<B>> consumer) {
|
||||
this.result.assertWithDiagnostics(() -> consumer.accept(this.result));
|
||||
return self();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private <T extends S> T self() {
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityExchangeResult<B> returnResult() {
|
||||
return this.result;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static class DefaultBodyContentSpec implements BodyContentSpec {
|
||||
|
||||
private final EntityExchangeResult<byte[]> result;
|
||||
|
||||
public DefaultBodyContentSpec(EntityExchangeResult<byte[]> result) {
|
||||
DefaultBodyContentSpec(EntityExchangeResult<byte[]> result) {
|
||||
this.result = result;
|
||||
}
|
||||
|
||||
@@ -373,57 +430,15 @@ class DefaultRestTestClient implements RestTestClient {
|
||||
return new String(body, charset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BodyContentSpec consumeWith(Consumer<EntityExchangeResult<byte[]>> consumer) {
|
||||
this.result.assertWithDiagnostics(() -> consumer.accept(this.result));
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityExchangeResult<byte[]> returnResult() {
|
||||
return this.result;
|
||||
}
|
||||
}
|
||||
|
||||
private static class DefaultBodySpec<B, S extends BodySpec<B, S>> implements BodySpec<B, S> {
|
||||
|
||||
private final EntityExchangeResult<B> result;
|
||||
|
||||
public DefaultBodySpec(@Nullable EntityExchangeResult<B> result) {
|
||||
this.result = Objects.requireNonNull(result, "exchangeResult must be non-null");
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityExchangeResult<B> returnResult() {
|
||||
return this.result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends S> T isEqualTo(B expected) {
|
||||
this.result.assertWithDiagnostics(() ->
|
||||
AssertionErrors.assertEquals("Response body", expected, this.result.getResponseBody()));
|
||||
return self();
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("NullAway") // https://github.com/uber/NullAway/issues/1129
|
||||
public <T extends S, R> T value(Function<B, R> bodyMapper, Matcher<? super R> matcher) {
|
||||
this.result.assertWithDiagnostics(() -> {
|
||||
B body = this.result.getResponseBody();
|
||||
MatcherAssert.assertThat(bodyMapper.apply(body), matcher);
|
||||
});
|
||||
return self();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends S> T value(Consumer<B> consumer) {
|
||||
this.result.assertWithDiagnostics(() -> consumer.accept(this.result.getResponseBody()));
|
||||
return self();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends S> T consumeWith(Consumer<EntityExchangeResult<B>> consumer) {
|
||||
this.result.assertWithDiagnostics(() -> consumer.accept(this.result));
|
||||
return self();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private <T extends S> T self() {
|
||||
return (T) this;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+20
-15
@@ -25,13 +25,17 @@ import org.springframework.web.util.UriBuilderFactory;
|
||||
|
||||
/**
|
||||
* Default implementation of {@link RestTestClient.Builder}.
|
||||
*
|
||||
* @author Rob Worsnop
|
||||
* @author Rossen Stoyanchev
|
||||
* @param <B> the type of the builder
|
||||
* @since 7.0
|
||||
*/
|
||||
class DefaultRestTestClientBuilder<B extends RestTestClient.Builder<B>> implements RestTestClient.Builder<B> {
|
||||
|
||||
protected final RestClient.Builder restClientBuilder;
|
||||
|
||||
|
||||
DefaultRestTestClientBuilder() {
|
||||
this.restClientBuilder = RestClient.builder();
|
||||
}
|
||||
@@ -40,11 +44,6 @@ class DefaultRestTestClientBuilder<B extends RestTestClient.Builder<B>> implemen
|
||||
this.restClientBuilder = restClientBuilder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RestTestClient.Builder<B> apply(Consumer<RestTestClient.Builder<B>> builderConsumer) {
|
||||
builderConsumer.accept(this);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RestTestClient.Builder<B> baseUrl(String baseUrl) {
|
||||
@@ -53,14 +52,8 @@ class DefaultRestTestClientBuilder<B extends RestTestClient.Builder<B>> implemen
|
||||
}
|
||||
|
||||
@Override
|
||||
public RestTestClient.Builder<B> defaultCookie(String cookieName, String... cookieValues) {
|
||||
this.restClientBuilder.defaultCookie(cookieName, cookieValues);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RestTestClient.Builder<B> defaultCookies(Consumer<MultiValueMap<String, String>> cookiesConsumer) {
|
||||
this.restClientBuilder.defaultCookies(cookiesConsumer);
|
||||
public RestTestClient.Builder<B> uriBuilderFactory(UriBuilderFactory uriFactory) {
|
||||
this.restClientBuilder.uriBuilderFactory(uriFactory);
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -77,8 +70,20 @@ class DefaultRestTestClientBuilder<B extends RestTestClient.Builder<B>> implemen
|
||||
}
|
||||
|
||||
@Override
|
||||
public RestTestClient.Builder<B> uriBuilderFactory(UriBuilderFactory uriFactory) {
|
||||
this.restClientBuilder.uriBuilderFactory(uriFactory);
|
||||
public RestTestClient.Builder<B> defaultCookie(String cookieName, String... cookieValues) {
|
||||
this.restClientBuilder.defaultCookie(cookieName, cookieValues);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RestTestClient.Builder<B> defaultCookies(Consumer<MultiValueMap<String, String>> cookiesConsumer) {
|
||||
this.restClientBuilder.defaultCookies(cookiesConsumer);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RestTestClient.Builder<B> apply(Consumer<RestTestClient.Builder<B>> builderConsumer) {
|
||||
builderConsumer.accept(this);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
+1
@@ -23,6 +23,7 @@ import org.springframework.test.web.support.AbstractHeaderAssertions;
|
||||
* Assertions on headers of the response.
|
||||
*
|
||||
* @author Rob Worsnop
|
||||
* @since 7.0
|
||||
* @see RestTestClient.ResponseSpec#expectHeader()
|
||||
*/
|
||||
public class HeaderAssertions extends AbstractHeaderAssertions<ExchangeResult, RestTestClient.ResponseSpec> {
|
||||
|
||||
+1
-1
@@ -26,7 +26,7 @@ import org.springframework.test.web.support.AbstractJsonPathAssertions;
|
||||
* <a href="https://github.com/jayway/JsonPath">JsonPath</a> assertions.
|
||||
*
|
||||
* @author Rob Worsnop
|
||||
*
|
||||
* @since 7.0
|
||||
* @see <a href="https://github.com/jayway/JsonPath">https://github.com/jayway/JsonPath</a>
|
||||
* @see JsonPathExpectationsHelper
|
||||
*/
|
||||
|
||||
+317
-294
@@ -63,6 +63,7 @@ public interface RestTestClient {
|
||||
*/
|
||||
String RESTTESTCLIENT_REQUEST_ID = "RestTestClient-Request-Id";
|
||||
|
||||
|
||||
/**
|
||||
* Prepare an HTTP GET request.
|
||||
* @return a spec for specifying the target URL
|
||||
@@ -111,11 +112,13 @@ public interface RestTestClient {
|
||||
*/
|
||||
RequestBodyUriSpec method(HttpMethod method);
|
||||
|
||||
|
||||
/**
|
||||
* Return a builder to mutate properties of this test client.
|
||||
*/
|
||||
<B extends Builder<B>> Builder<B> mutate();
|
||||
|
||||
|
||||
/**
|
||||
* Begin creating a {@link RestTestClient} by providing the {@code @Controller}
|
||||
* instance(s) to handle requests with.
|
||||
@@ -184,239 +187,78 @@ public interface RestTestClient {
|
||||
return new DefaultRestTestClientBuilder<>(RestClient.builder().requestFactory(requestFactory));
|
||||
}
|
||||
|
||||
/**
|
||||
* Specification for providing request headers and the URI of a request.
|
||||
*
|
||||
* @param <S> a self reference to the spec type
|
||||
*/
|
||||
interface RequestHeadersUriSpec<S extends RequestHeadersSpec<S>> extends UriSpec<S>, RequestHeadersSpec<S> {
|
||||
|
||||
interface Builder<B extends Builder<B>> {
|
||||
|
||||
/**
|
||||
* Configure a base URI as described in
|
||||
* {@link RestClient#create(String)
|
||||
* WebClient.create(String)}.
|
||||
*/
|
||||
Builder<B> baseUrl(String baseUrl);
|
||||
|
||||
/**
|
||||
* Provide a pre-configured {@link UriBuilderFactory} instance as an
|
||||
* alternative to and effectively overriding {@link #baseUrl(String)}.
|
||||
*/
|
||||
Builder<B> uriBuilderFactory(UriBuilderFactory uriBuilderFactory);
|
||||
|
||||
/**
|
||||
* Add the given header to all requests that haven't added it.
|
||||
* @param headerName the header name
|
||||
* @param headerValues the header values
|
||||
*/
|
||||
Builder<B> defaultHeader(String headerName, String... headerValues);
|
||||
|
||||
/**
|
||||
* Manipulate the default headers with the given consumer. The
|
||||
* headers provided to the consumer are "live", so that the consumer can be used to
|
||||
* {@linkplain HttpHeaders#set(String, String) overwrite} existing header values,
|
||||
* {@linkplain HttpHeaders#remove(String) remove} values, or use any of the other
|
||||
* {@link HttpHeaders} methods.
|
||||
* @param headersConsumer a function that consumes the {@code HttpHeaders}
|
||||
* @return this builder
|
||||
*/
|
||||
Builder<B> defaultHeaders(Consumer<HttpHeaders> headersConsumer);
|
||||
|
||||
/**
|
||||
* Add the given cookie to all requests.
|
||||
* @param cookieName the cookie name
|
||||
* @param cookieValues the cookie values
|
||||
*/
|
||||
Builder<B> defaultCookie(String cookieName, String... cookieValues);
|
||||
|
||||
/**
|
||||
* Manipulate the default cookies with the given consumer. The
|
||||
* map provided to the consumer is "live", so that the consumer can be used to
|
||||
* {@linkplain MultiValueMap#set(Object, Object) overwrite} existing header values,
|
||||
* {@linkplain MultiValueMap#remove(Object) remove} values, or use any of the other
|
||||
* {@link MultiValueMap} methods.
|
||||
* @param cookiesConsumer a function that consumes the cookies map
|
||||
* @return this builder
|
||||
*/
|
||||
Builder<B> defaultCookies(Consumer<MultiValueMap<String, String>> cookiesConsumer);
|
||||
|
||||
/**
|
||||
* Apply the given {@code Consumer} to this builder instance.
|
||||
* <p>This can be useful for applying pre-packaged customizations.
|
||||
* @param builderConsumer the consumer to apply
|
||||
*/
|
||||
Builder<B> apply(Consumer<Builder<B>> builderConsumer);
|
||||
|
||||
/**
|
||||
* Build the {@link RestTestClient} instance.
|
||||
*/
|
||||
RestTestClient build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Specification for providing the body and the URI of a request.
|
||||
*/
|
||||
interface RequestBodyUriSpec extends RequestBodySpec, RequestHeadersUriSpec<RequestBodySpec> {
|
||||
|
||||
interface MockServerBuilder<M extends MockMvcBuilder> extends Builder<MockServerBuilder<M>> {
|
||||
|
||||
MockServerBuilder<M> configureServer(Consumer<M> consumer);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Chained API for applying assertions to a response.
|
||||
*/
|
||||
interface ResponseSpec {
|
||||
/**
|
||||
* Assertions on the response status.
|
||||
*/
|
||||
StatusAssertions expectStatus();
|
||||
|
||||
/**
|
||||
* Consume and decode the response body to {@code byte[]} and then apply
|
||||
* assertions on the raw content (for example, isEmpty, JSONPath, etc.).
|
||||
*/
|
||||
BodyContentSpec expectBody();
|
||||
|
||||
/**
|
||||
* Consume and decode the response body to a single object of type
|
||||
* {@code <B>} and then apply assertions.
|
||||
* @param bodyType the expected body type
|
||||
*/
|
||||
<B> BodySpec<B, ?> expectBody(Class<B> bodyType);
|
||||
|
||||
/**
|
||||
* Alternative to {@link #expectBody(Class)} that accepts information
|
||||
* about a target type with generics.
|
||||
*/
|
||||
<B> BodySpec<B, ?> expectBody(ParameterizedTypeReference<B> bodyType);
|
||||
|
||||
/**
|
||||
* Assertions on the cookies of the response.
|
||||
*/
|
||||
CookieAssertions expectCookie();
|
||||
|
||||
/**
|
||||
* Assertions on the headers of the response.
|
||||
*/
|
||||
HeaderAssertions expectHeader();
|
||||
|
||||
/**
|
||||
* Apply multiple assertions to a response with the given
|
||||
* {@linkplain RestTestClient.ResponseSpec.ResponseSpecConsumer consumers}, with the guarantee that
|
||||
* all assertions will be applied even if one or more assertions fails
|
||||
* with an exception.
|
||||
* <p>If a single {@link Error} or {@link RuntimeException} is thrown,
|
||||
* it will be rethrown.
|
||||
* <p>If multiple exceptions are thrown, this method will throw an
|
||||
* {@link AssertionError} whose error message is a summary of all the
|
||||
* exceptions. In addition, each exception will be added as a
|
||||
* {@linkplain Throwable#addSuppressed(Throwable) suppressed exception} to
|
||||
* the {@code AssertionError}.
|
||||
* <p>This feature is similar to the {@code SoftAssertions} support in
|
||||
* AssertJ and the {@code assertAll()} support in JUnit Jupiter.
|
||||
*
|
||||
* <h4>Example</h4>
|
||||
* <pre class="code">
|
||||
* restTestClient.get().uri("/hello").exchange()
|
||||
* .expectAll(
|
||||
* responseSpec -> responseSpec.expectStatus().isOk(),
|
||||
* responseSpec -> responseSpec.expectBody(String.class).isEqualTo("Hello, World!")
|
||||
* );
|
||||
* </pre>
|
||||
* @param consumers the list of {@code ResponseSpec} consumers
|
||||
*/
|
||||
ResponseSpec expectAll(ResponseSpecConsumer... consumers);
|
||||
|
||||
/**
|
||||
* Exit the chained flow in order to consume the response body
|
||||
* externally.
|
||||
*/
|
||||
<T> EntityExchangeResult<T> returnResult(Class<T> elementClass);
|
||||
|
||||
/**
|
||||
* Alternative to {@link #returnResult(Class)} that accepts information
|
||||
* about a target type with generics.
|
||||
*/
|
||||
<T> EntityExchangeResult<T> returnResult(ParameterizedTypeReference<T> elementTypeRef);
|
||||
|
||||
/**
|
||||
* {@link Consumer} of a {@link RestTestClient.ResponseSpec}.
|
||||
* @see RestTestClient.ResponseSpec#expectAll(RestTestClient.ResponseSpec.ResponseSpecConsumer...)
|
||||
*/
|
||||
@FunctionalInterface
|
||||
interface ResponseSpecConsumer extends Consumer<ResponseSpec> {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Spec for expectations on the response body content.
|
||||
*/
|
||||
interface BodyContentSpec {
|
||||
/**
|
||||
* Assert the response body is empty and return the exchange result.
|
||||
*/
|
||||
EntityExchangeResult<Void> isEmpty();
|
||||
|
||||
/**
|
||||
* Parse the expected and actual response content as JSON and perform a
|
||||
* comparison verifying that they contain the same attribute-value pairs
|
||||
* regardless of formatting with <em>lenient</em> checking (extensible
|
||||
* and non-strict array ordering).
|
||||
* <p>Use of this method requires the
|
||||
* <a href="https://jsonassert.skyscreamer.org/">JSONassert</a> library
|
||||
* to be on the classpath.
|
||||
* @param expectedJson the expected JSON content
|
||||
* @see #json(String, JsonCompareMode)
|
||||
*/
|
||||
default BodyContentSpec json(String expectedJson) {
|
||||
return json(expectedJson, JsonCompareMode.LENIENT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the expected and actual response content as JSON and perform a
|
||||
* comparison using the given {@linkplain JsonCompareMode mode}. If the
|
||||
* comparison failed, throws an {@link AssertionError} with the message
|
||||
* of the {@link JsonComparison}.
|
||||
* <p>Use of this method requires the
|
||||
* <a href="https://jsonassert.skyscreamer.org/">JSONassert</a> library
|
||||
* to be on the classpath.
|
||||
* @param expectedJson the expected JSON content
|
||||
* @param compareMode the compare mode
|
||||
* @see #json(String)
|
||||
*/
|
||||
BodyContentSpec json(String expectedJson, JsonCompareMode compareMode);
|
||||
|
||||
/**
|
||||
* Parse the expected and actual response content as JSON and perform a
|
||||
* comparison using the given {@link JsonComparator}. If the comparison
|
||||
* failed, throws an {@link AssertionError} with the message of the
|
||||
* {@link JsonComparison}.
|
||||
* @param expectedJson the expected JSON content
|
||||
* @param comparator the comparator to use
|
||||
*/
|
||||
BodyContentSpec json(String expectedJson, JsonComparator comparator);
|
||||
|
||||
/**
|
||||
* Parse expected and actual response content as XML and assert that
|
||||
* the two are "similar", i.e. they contain the same elements and
|
||||
* attributes regardless of order.
|
||||
* <p>Use of this method requires the
|
||||
* <a href="https://github.com/xmlunit/xmlunit">XMLUnit</a> library on
|
||||
* the classpath.
|
||||
* @param expectedXml the expected XML content.
|
||||
* @see org.springframework.test.util.XmlExpectationsHelper#assertXmlEqual(String, String)
|
||||
*/
|
||||
BodyContentSpec xml(String expectedXml);
|
||||
|
||||
/**
|
||||
* Access to response body assertions using an XPath expression to
|
||||
* inspect a specific subset of the body.
|
||||
* <p>The XPath expression can be a parameterized string using
|
||||
* formatting specifiers as defined in {@link String#format}.
|
||||
* @param expression the XPath expression
|
||||
* @param args arguments to parameterize the expression
|
||||
* @see #xpath(String, Map, Object...)
|
||||
*/
|
||||
default XpathAssertions xpath(String expression, Object... args) {
|
||||
return xpath(expression, null, args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Access to response body assertions with specific namespaces using an
|
||||
* XPath expression to inspect a specific subset of the body.
|
||||
* <p>The XPath expression can be a parameterized string using
|
||||
* formatting specifiers as defined in {@link String#format}.
|
||||
* @param expression the XPath expression
|
||||
* @param namespaces the namespaces to use
|
||||
* @param args arguments to parameterize the expression
|
||||
*/
|
||||
XpathAssertions xpath(String expression, @Nullable Map<String, String> namespaces, Object... args);
|
||||
|
||||
/**
|
||||
* Access to response body assertions using a
|
||||
* <a href="https://github.com/jayway/JsonPath">JsonPath</a> expression
|
||||
* to inspect a specific subset of the body.
|
||||
* @param expression the JsonPath expression
|
||||
*/
|
||||
JsonPathAssertions jsonPath(String expression);
|
||||
|
||||
/**
|
||||
* Exit the chained API and return an {@code ExchangeResult} with the
|
||||
* raw response content.
|
||||
*/
|
||||
EntityExchangeResult<byte[]> returnResult();
|
||||
}
|
||||
|
||||
/**
|
||||
* Spec for expectations on the response body decoded to a single Object.
|
||||
*
|
||||
* @param <S> a self reference to the spec type
|
||||
* @param <B> the body type
|
||||
*/
|
||||
interface BodySpec<B, S extends BodySpec<B, S>> {
|
||||
/**
|
||||
* Transform the extracted the body with a function, for example, extracting a
|
||||
* property, and assert the mapped value with a {@link Matcher}.
|
||||
*/
|
||||
<T extends S, R> T value(Function<B, R> bodyMapper, Matcher<? super R> matcher);
|
||||
|
||||
/**
|
||||
* Assert the extracted body with a {@link Consumer}.
|
||||
*/
|
||||
<T extends S> T value(Consumer<B> consumer);
|
||||
|
||||
/**
|
||||
* Assert the exchange result with the given {@link Consumer}.
|
||||
*/
|
||||
<T extends S> T consumeWith(Consumer<EntityExchangeResult<B>> consumer);
|
||||
|
||||
/**
|
||||
* Exit the chained API and return an {@code EntityExchangeResult} with the
|
||||
* decoded response content.
|
||||
*/
|
||||
EntityExchangeResult<B> returnResult();
|
||||
|
||||
/**
|
||||
* Assert the extracted body is equal to the given value.
|
||||
*/
|
||||
<T extends S> T isEqualTo(B expected);
|
||||
}
|
||||
|
||||
/**
|
||||
* Specification for providing the URI of a request.
|
||||
@@ -424,6 +266,7 @@ public interface RestTestClient {
|
||||
* @param <S> a self reference to the spec type
|
||||
*/
|
||||
interface UriSpec<S extends RequestHeadersSpec<?>> {
|
||||
|
||||
/**
|
||||
* Specify the URI using an absolute, fully constructed {@link java.net.URI}.
|
||||
* <p>If a {@link UriBuilderFactory} was configured for the client with
|
||||
@@ -457,12 +300,9 @@ public interface RestTestClient {
|
||||
* @return spec to add headers or perform the exchange
|
||||
*/
|
||||
S uri(Function<UriBuilder, URI> uriFunction);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Specification for adding request headers and performing an exchange.
|
||||
*
|
||||
@@ -564,6 +404,7 @@ public interface RestTestClient {
|
||||
ResponseSpec exchange();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Specification for providing body of a request.
|
||||
*/
|
||||
@@ -587,70 +428,252 @@ public interface RestTestClient {
|
||||
RequestHeadersSpec<?> body(Object body);
|
||||
}
|
||||
|
||||
interface Builder<B extends Builder<B>> {
|
||||
/**
|
||||
* Apply the given {@code Consumer} to this builder instance.
|
||||
* <p>This can be useful for applying pre-packaged customizations.
|
||||
* @param builderConsumer the consumer to apply
|
||||
*/
|
||||
Builder<B> apply(Consumer<Builder<B>> builderConsumer);
|
||||
|
||||
/**
|
||||
* Add the given cookie to all requests.
|
||||
* @param cookieName the cookie name
|
||||
* @param cookieValues the cookie values
|
||||
*/
|
||||
Builder<B> defaultCookie(String cookieName, String... cookieValues);
|
||||
|
||||
/**
|
||||
* Manipulate the default cookies with the given consumer. The
|
||||
* map provided to the consumer is "live", so that the consumer can be used to
|
||||
* {@linkplain MultiValueMap#set(Object, Object) overwrite} existing header values,
|
||||
* {@linkplain MultiValueMap#remove(Object) remove} values, or use any of the other
|
||||
* {@link MultiValueMap} methods.
|
||||
* @param cookiesConsumer a function that consumes the cookies map
|
||||
* @return this builder
|
||||
*/
|
||||
Builder<B> defaultCookies(Consumer<MultiValueMap<String, String>> cookiesConsumer);
|
||||
|
||||
/**
|
||||
* Add the given header to all requests that haven't added it.
|
||||
* @param headerName the header name
|
||||
* @param headerValues the header values
|
||||
*/
|
||||
Builder<B> defaultHeader(String headerName, String... headerValues);
|
||||
|
||||
/**
|
||||
* Manipulate the default headers with the given consumer. The
|
||||
* headers provided to the consumer are "live", so that the consumer can be used to
|
||||
* {@linkplain HttpHeaders#set(String, String) overwrite} existing header values,
|
||||
* {@linkplain HttpHeaders#remove(String) remove} values, or use any of the other
|
||||
* {@link HttpHeaders} methods.
|
||||
* @param headersConsumer a function that consumes the {@code HttpHeaders}
|
||||
* @return this builder
|
||||
*/
|
||||
Builder<B> defaultHeaders(Consumer<HttpHeaders> headersConsumer);
|
||||
|
||||
/**
|
||||
* Provide a pre-configured {@link UriBuilderFactory} instance as an
|
||||
* alternative to and effectively overriding {@link #baseUrl(String)}.
|
||||
*/
|
||||
Builder<B> uriBuilderFactory(UriBuilderFactory uriFactory);
|
||||
|
||||
/**
|
||||
* Build the {@link RestTestClient} instance.
|
||||
*/
|
||||
RestTestClient build();
|
||||
|
||||
/**
|
||||
* Configure a base URI as described in
|
||||
* {@link RestClient#create(String)
|
||||
* WebClient.create(String)}.
|
||||
*/
|
||||
Builder<B> baseUrl(String baseUrl);
|
||||
/**
|
||||
* Specification for providing request headers and the URI of a request.
|
||||
*
|
||||
* @param <S> a self reference to the spec type
|
||||
*/
|
||||
interface RequestHeadersUriSpec<S extends RequestHeadersSpec<S>> extends UriSpec<S>, RequestHeadersSpec<S> {
|
||||
}
|
||||
|
||||
interface MockServerBuilder<M extends MockMvcBuilder> extends Builder<MockServerBuilder<M>> {
|
||||
MockServerBuilder<M> configureServer(Consumer<M> consumer);
|
||||
|
||||
/**
|
||||
* Specification for providing the body and the URI of a request.
|
||||
*/
|
||||
interface RequestBodyUriSpec extends RequestBodySpec, RequestHeadersUriSpec<RequestBodySpec> {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Chained API for applying assertions to a response.
|
||||
*/
|
||||
interface ResponseSpec {
|
||||
|
||||
/**
|
||||
* Apply multiple assertions to a response with the given
|
||||
* {@linkplain RestTestClient.ResponseSpec.ResponseSpecConsumer consumers}, with the guarantee that
|
||||
* all assertions will be applied even if one or more assertions fails
|
||||
* with an exception.
|
||||
* <p>If a single {@link Error} or {@link RuntimeException} is thrown,
|
||||
* it will be rethrown.
|
||||
* <p>If multiple exceptions are thrown, this method will throw an
|
||||
* {@link AssertionError} whose error message is a summary of all the
|
||||
* exceptions. In addition, each exception will be added as a
|
||||
* {@linkplain Throwable#addSuppressed(Throwable) suppressed exception} to
|
||||
* the {@code AssertionError}.
|
||||
* <p>This feature is similar to the {@code SoftAssertions} support in
|
||||
* AssertJ and the {@code assertAll()} support in JUnit Jupiter.
|
||||
*
|
||||
* <h4>Example</h4>
|
||||
* <pre class="code">
|
||||
* restTestClient.get().uri("/hello").exchange()
|
||||
* .expectAll(
|
||||
* responseSpec -> responseSpec.expectStatus().isOk(),
|
||||
* responseSpec -> responseSpec.expectBody(String.class).isEqualTo("Hello, World!")
|
||||
* );
|
||||
* </pre>
|
||||
* @param consumers the list of {@code ResponseSpec} consumers
|
||||
*/
|
||||
ResponseSpec expectAll(ResponseSpecConsumer... consumers);
|
||||
|
||||
/**
|
||||
* Assertions on the response status.
|
||||
*/
|
||||
StatusAssertions expectStatus();
|
||||
|
||||
/**
|
||||
* Assertions on the headers of the response.
|
||||
*/
|
||||
HeaderAssertions expectHeader();
|
||||
|
||||
/**
|
||||
* Assertions on the cookies of the response.
|
||||
*/
|
||||
CookieAssertions expectCookie();
|
||||
|
||||
/**
|
||||
* Consume and decode the response body to a single object of type
|
||||
* {@code <B>} and then apply assertions.
|
||||
* @param bodyType the expected body type
|
||||
*/
|
||||
<B> BodySpec<B, ?> expectBody(Class<B> bodyType);
|
||||
|
||||
/**
|
||||
* Alternative to {@link #expectBody(Class)} that accepts information
|
||||
* about a target type with generics.
|
||||
*/
|
||||
<B> BodySpec<B, ?> expectBody(ParameterizedTypeReference<B> bodyType);
|
||||
|
||||
/**
|
||||
* Consume and decode the response body to {@code byte[]} and then apply
|
||||
* assertions on the raw content (for example, isEmpty, JSONPath, etc.).
|
||||
*/
|
||||
BodyContentSpec expectBody();
|
||||
|
||||
/**
|
||||
* Exit the chained flow in order to consume the response body
|
||||
* externally.
|
||||
*/
|
||||
<T> EntityExchangeResult<T> returnResult(Class<T> elementClass);
|
||||
|
||||
/**
|
||||
* Alternative to {@link #returnResult(Class)} that accepts information
|
||||
* about a target type with generics.
|
||||
*/
|
||||
<T> EntityExchangeResult<T> returnResult(ParameterizedTypeReference<T> elementTypeRef);
|
||||
|
||||
/**
|
||||
* {@link Consumer} of a {@link RestTestClient.ResponseSpec}.
|
||||
* @see RestTestClient.ResponseSpec#expectAll(RestTestClient.ResponseSpec.ResponseSpecConsumer...)
|
||||
*/
|
||||
@FunctionalInterface
|
||||
interface ResponseSpecConsumer extends Consumer<ResponseSpec> {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Spec for expectations on the response body decoded to a single Object.
|
||||
*
|
||||
* @param <S> a self reference to the spec type
|
||||
* @param <B> the body type
|
||||
*/
|
||||
interface BodySpec<B, S extends BodySpec<B, S>> {
|
||||
|
||||
/**
|
||||
* Assert the extracted body is equal to the given value.
|
||||
*/
|
||||
<T extends S> T isEqualTo(B expected);
|
||||
|
||||
/**
|
||||
* Transform the extracted the body with a function, for example, extracting a
|
||||
* property, and assert the mapped value with a {@link Matcher}.
|
||||
*/
|
||||
<T extends S, R> T value(Function<B, R> bodyMapper, Matcher<? super R> matcher);
|
||||
|
||||
/**
|
||||
* Assert the extracted body with a {@link Consumer}.
|
||||
*/
|
||||
<T extends S> T value(Consumer<B> consumer);
|
||||
|
||||
/**
|
||||
* Assert the exchange result with the given {@link Consumer}.
|
||||
*/
|
||||
<T extends S> T consumeWith(Consumer<EntityExchangeResult<B>> consumer);
|
||||
|
||||
/**
|
||||
* Exit the chained API and return an {@code EntityExchangeResult} with the
|
||||
* decoded response content.
|
||||
*/
|
||||
EntityExchangeResult<B> returnResult();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Spec for expectations on the response body content.
|
||||
*/
|
||||
interface BodyContentSpec {
|
||||
/**
|
||||
* Assert the response body is empty and return the exchange result.
|
||||
*/
|
||||
EntityExchangeResult<Void> isEmpty();
|
||||
|
||||
/**
|
||||
* Parse the expected and actual response content as JSON and perform a
|
||||
* comparison verifying that they contain the same attribute-value pairs
|
||||
* regardless of formatting with <em>lenient</em> checking (extensible
|
||||
* and non-strict array ordering).
|
||||
* <p>Use of this method requires the
|
||||
* <a href="https://jsonassert.skyscreamer.org/">JSONassert</a> library
|
||||
* to be on the classpath.
|
||||
* @param expectedJson the expected JSON content
|
||||
* @see #json(String, JsonCompareMode)
|
||||
*/
|
||||
default BodyContentSpec json(String expectedJson) {
|
||||
return json(expectedJson, JsonCompareMode.LENIENT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the expected and actual response content as JSON and perform a
|
||||
* comparison using the given {@linkplain JsonCompareMode mode}. If the
|
||||
* comparison failed, throws an {@link AssertionError} with the message
|
||||
* of the {@link JsonComparison}.
|
||||
* <p>Use of this method requires the
|
||||
* <a href="https://jsonassert.skyscreamer.org/">JSONassert</a> library
|
||||
* to be on the classpath.
|
||||
* @param expectedJson the expected JSON content
|
||||
* @param compareMode the compare mode
|
||||
* @see #json(String)
|
||||
*/
|
||||
BodyContentSpec json(String expectedJson, JsonCompareMode compareMode);
|
||||
|
||||
/**
|
||||
* Parse the expected and actual response content as JSON and perform a
|
||||
* comparison using the given {@link JsonComparator}. If the comparison
|
||||
* failed, throws an {@link AssertionError} with the message of the
|
||||
* {@link JsonComparison}.
|
||||
* @param expectedJson the expected JSON content
|
||||
* @param comparator the comparator to use
|
||||
*/
|
||||
BodyContentSpec json(String expectedJson, JsonComparator comparator);
|
||||
|
||||
/**
|
||||
* Parse expected and actual response content as XML and assert that
|
||||
* the two are "similar", i.e. they contain the same elements and
|
||||
* attributes regardless of order.
|
||||
* <p>Use of this method requires the
|
||||
* <a href="https://github.com/xmlunit/xmlunit">XMLUnit</a> library on
|
||||
* the classpath.
|
||||
* @param expectedXml the expected XML content.
|
||||
* @see org.springframework.test.util.XmlExpectationsHelper#assertXmlEqual(String, String)
|
||||
*/
|
||||
BodyContentSpec xml(String expectedXml);
|
||||
|
||||
/**
|
||||
* Access to response body assertions using a
|
||||
* <a href="https://github.com/jayway/JsonPath">JsonPath</a> expression
|
||||
* to inspect a specific subset of the body.
|
||||
* @param expression the JsonPath expression
|
||||
*/
|
||||
JsonPathAssertions jsonPath(String expression);
|
||||
|
||||
/**
|
||||
* Access to response body assertions using an XPath expression to
|
||||
* inspect a specific subset of the body.
|
||||
* <p>The XPath expression can be a parameterized string using
|
||||
* formatting specifiers as defined in {@link String#format}.
|
||||
* @param expression the XPath expression
|
||||
* @param args arguments to parameterize the expression
|
||||
* @see #xpath(String, Map, Object...)
|
||||
*/
|
||||
default XpathAssertions xpath(String expression, Object... args) {
|
||||
return xpath(expression, null, args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Access to response body assertions with specific namespaces using an
|
||||
* XPath expression to inspect a specific subset of the body.
|
||||
* <p>The XPath expression can be a parameterized string using
|
||||
* formatting specifiers as defined in {@link String#format}.
|
||||
* @param expression the XPath expression
|
||||
* @param namespaces the namespaces to use
|
||||
* @param args arguments to parameterize the expression
|
||||
*/
|
||||
XpathAssertions xpath(String expression, @Nullable Map<String, String> namespaces, Object... args);
|
||||
|
||||
/**
|
||||
* Assert the response body content with the given {@link Consumer}.
|
||||
* @param consumer the consumer for the response body; the input
|
||||
* {@code byte[]} may be {@code null} if there was no response body.
|
||||
*/
|
||||
BodyContentSpec consumeWith(Consumer<EntityExchangeResult<byte[]>> consumer);
|
||||
|
||||
/**
|
||||
* Exit the chained API and return an {@code ExchangeResult} with the
|
||||
* raw response content.
|
||||
*/
|
||||
EntityExchangeResult<byte[]> returnResult();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+1
-1
@@ -24,7 +24,7 @@ import org.springframework.test.web.support.AbstractStatusAssertions;
|
||||
* Assertions on the response status.
|
||||
*
|
||||
* @author Rob Worsnop
|
||||
*
|
||||
* @since 7.0
|
||||
* @see ResponseSpec#expectStatus()
|
||||
*/
|
||||
public class StatusAssertions extends AbstractStatusAssertions<ExchangeResult, RestTestClient.ResponseSpec> {
|
||||
|
||||
+1
@@ -29,6 +29,7 @@ import org.springframework.util.Assert;
|
||||
* XPath assertions for the {@link RestTestClient}.
|
||||
*
|
||||
* @author Rob Worsnop
|
||||
* @since 7.0
|
||||
*/
|
||||
public class XpathAssertions extends AbstractXpathAssertions<RestTestClient.BodyContentSpec> {
|
||||
|
||||
|
||||
Reference in New Issue
Block a user