|
|
|
|
@ -63,6 +63,7 @@ public interface RestTestClient {
@@ -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 {
@@ -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 {
@@ -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> { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 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 { |
|
|
|
|
/** |
|
|
|
|
* 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(); |
|
|
|
|
interface Builder<B extends Builder<B>> { |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Consume and decode the response body to a single object of type |
|
|
|
|
* {@code <B>} and then apply assertions. |
|
|
|
|
* @param bodyType the expected body type |
|
|
|
|
* Configure a base URI as described in |
|
|
|
|
* {@link RestClient#create(String) |
|
|
|
|
* WebClient.create(String)}. |
|
|
|
|
*/ |
|
|
|
|
<B> BodySpec<B, ?> expectBody(Class<B> bodyType); |
|
|
|
|
Builder<B> baseUrl(String baseUrl); |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Alternative to {@link #expectBody(Class)} that accepts information |
|
|
|
|
* about a target type with generics. |
|
|
|
|
* Provide a pre-configured {@link UriBuilderFactory} instance as an |
|
|
|
|
* alternative to and effectively overriding {@link #baseUrl(String)}. |
|
|
|
|
*/ |
|
|
|
|
<B> BodySpec<B, ?> expectBody(ParameterizedTypeReference<B> bodyType); |
|
|
|
|
Builder<B> uriBuilderFactory(UriBuilderFactory uriBuilderFactory); |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Assertions on the cookies of the response. |
|
|
|
|
* Add the given header to all requests that haven't added it. |
|
|
|
|
* @param headerName the header name |
|
|
|
|
* @param headerValues the header values |
|
|
|
|
*/ |
|
|
|
|
CookieAssertions expectCookie(); |
|
|
|
|
Builder<B> defaultHeader(String headerName, String... headerValues); |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Assertions on the headers of the response. |
|
|
|
|
* 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 |
|
|
|
|
*/ |
|
|
|
|
HeaderAssertions expectHeader(); |
|
|
|
|
Builder<B> defaultHeaders(Consumer<HttpHeaders> headersConsumer); |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 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 |
|
|
|
|
* Add the given cookie to all requests. |
|
|
|
|
* @param cookieName the cookie name |
|
|
|
|
* @param cookieValues the cookie values |
|
|
|
|
*/ |
|
|
|
|
ResponseSpec expectAll(ResponseSpecConsumer... consumers); |
|
|
|
|
Builder<B> defaultCookie(String cookieName, String... cookieValues); |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Exit the chained flow in order to consume the response body |
|
|
|
|
* externally. |
|
|
|
|
* 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 |
|
|
|
|
*/ |
|
|
|
|
<T> EntityExchangeResult<T> returnResult(Class<T> elementClass); |
|
|
|
|
Builder<B> defaultCookies(Consumer<MultiValueMap<String, String>> cookiesConsumer); |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Alternative to {@link #returnResult(Class)} that accepts information |
|
|
|
|
* about a target type with generics. |
|
|
|
|
* 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 |
|
|
|
|
*/ |
|
|
|
|
<T> EntityExchangeResult<T> returnResult(ParameterizedTypeReference<T> elementTypeRef); |
|
|
|
|
Builder<B> apply(Consumer<Builder<B>> builderConsumer); |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* {@link Consumer} of a {@link RestTestClient.ResponseSpec}. |
|
|
|
|
* @see RestTestClient.ResponseSpec#expectAll(RestTestClient.ResponseSpec.ResponseSpecConsumer...) |
|
|
|
|
* Build the {@link RestTestClient} instance. |
|
|
|
|
*/ |
|
|
|
|
@FunctionalInterface |
|
|
|
|
interface ResponseSpecConsumer extends Consumer<ResponseSpec> { |
|
|
|
|
} |
|
|
|
|
RestTestClient build(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 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); |
|
|
|
|
interface MockServerBuilder<M extends MockMvcBuilder> extends Builder<MockServerBuilder<M>> { |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 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); |
|
|
|
|
MockServerBuilder<M> configureServer(Consumer<M> consumer); |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 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 {
@@ -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 {
@@ -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 {
@@ -564,6 +404,7 @@ public interface RestTestClient {
|
|
|
|
|
ResponseSpec exchange(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Specification for providing body of a request. |
|
|
|
|
*/ |
|
|
|
|
@ -587,70 +428,252 @@ public interface RestTestClient {
@@ -587,70 +428,252 @@ public interface RestTestClient {
|
|
|
|
|
RequestHeadersSpec<?> body(Object body); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
interface Builder<B extends Builder<B>> { |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 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> { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 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 the given {@code Consumer} to this builder instance. |
|
|
|
|
* <p>This can be useful for applying pre-packaged customizations. |
|
|
|
|
* @param builderConsumer the consumer to apply |
|
|
|
|
* 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 |
|
|
|
|
*/ |
|
|
|
|
Builder<B> apply(Consumer<Builder<B>> builderConsumer); |
|
|
|
|
ResponseSpec expectAll(ResponseSpecConsumer... consumers); |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Add the given cookie to all requests. |
|
|
|
|
* @param cookieName the cookie name |
|
|
|
|
* @param cookieValues the cookie values |
|
|
|
|
* Assertions on the response status. |
|
|
|
|
*/ |
|
|
|
|
Builder<B> defaultCookie(String cookieName, String... cookieValues); |
|
|
|
|
StatusAssertions expectStatus(); |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 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 |
|
|
|
|
* Assertions on the headers of the response. |
|
|
|
|
*/ |
|
|
|
|
Builder<B> defaultCookies(Consumer<MultiValueMap<String, String>> cookiesConsumer); |
|
|
|
|
HeaderAssertions expectHeader(); |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Add the given header to all requests that haven't added it. |
|
|
|
|
* @param headerName the header name |
|
|
|
|
* @param headerValues the header values |
|
|
|
|
* Assertions on the cookies of the response. |
|
|
|
|
*/ |
|
|
|
|
Builder<B> defaultHeader(String headerName, String... headerValues); |
|
|
|
|
CookieAssertions expectCookie(); |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 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 |
|
|
|
|
* Consume and decode the response body to a single object of type |
|
|
|
|
* {@code <B>} and then apply assertions. |
|
|
|
|
* @param bodyType the expected body type |
|
|
|
|
*/ |
|
|
|
|
Builder<B> defaultHeaders(Consumer<HttpHeaders> headersConsumer); |
|
|
|
|
<B> BodySpec<B, ?> expectBody(Class<B> bodyType); |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Provide a pre-configured {@link UriBuilderFactory} instance as an |
|
|
|
|
* alternative to and effectively overriding {@link #baseUrl(String)}. |
|
|
|
|
* Alternative to {@link #expectBody(Class)} that accepts information |
|
|
|
|
* about a target type with generics. |
|
|
|
|
*/ |
|
|
|
|
Builder<B> uriBuilderFactory(UriBuilderFactory uriFactory); |
|
|
|
|
<B> BodySpec<B, ?> expectBody(ParameterizedTypeReference<B> bodyType); |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Build the {@link RestTestClient} instance. |
|
|
|
|
* Consume and decode the response body to {@code byte[]} and then apply |
|
|
|
|
* assertions on the raw content (for example, isEmpty, JSONPath, etc.). |
|
|
|
|
*/ |
|
|
|
|
RestTestClient build(); |
|
|
|
|
BodyContentSpec expectBody(); |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Configure a base URI as described in |
|
|
|
|
* {@link RestClient#create(String) |
|
|
|
|
* WebClient.create(String)}. |
|
|
|
|
* Exit the chained flow in order to consume the response body |
|
|
|
|
* externally. |
|
|
|
|
*/ |
|
|
|
|
Builder<B> baseUrl(String baseUrl); |
|
|
|
|
<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> { |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
interface MockServerBuilder<M extends MockMvcBuilder> extends Builder<MockServerBuilder<M>> { |
|
|
|
|
MockServerBuilder<M> configureServer(Consumer<M> consumer); |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 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(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|