Polish AssertJ support for MockMvc

See gh-21178
This commit is contained in:
Sam Brannen
2024-03-15 17:15:32 +01:00
parent 4a74e1fc2d
commit cf31d088e2
31 changed files with 276 additions and 258 deletions

View File

@@ -36,14 +36,15 @@ import org.springframework.util.StringUtils;
*/
public class MediaTypeAssert extends AbstractObjectAssert<MediaTypeAssert, MediaType> {
public MediaTypeAssert(@Nullable String actual) {
this(StringUtils.hasText(actual) ? MediaType.parseMediaType(actual) : null);
}
public MediaTypeAssert(@Nullable MediaType mediaType) {
super(mediaType, MediaTypeAssert.class);
as("Media type");
}
public MediaTypeAssert(@Nullable String actual) {
this(StringUtils.hasText(actual) ? MediaType.parseMediaType(actual) : null);
}
/**
* Verify that the actual media type is equal to the given string
@@ -57,7 +58,8 @@ public class MediaTypeAssert extends AbstractObjectAssert<MediaTypeAssert, Media
/**
* Verify that the actual media type is
* {@linkplain MediaType#isCompatibleWith(MediaType) compatible} with the
* given one. Example: <pre><code class='java'>
* given one.
* <p>Example: <pre><code class='java'>
* // Check that actual is compatible with "application/json"
* assertThat(mediaType).isCompatibleWith(MediaType.APPLICATION_JSON);
* </code></pre>
@@ -77,7 +79,8 @@ public class MediaTypeAssert extends AbstractObjectAssert<MediaTypeAssert, Media
/**
* Verify that the actual media type is
* {@linkplain MediaType#isCompatibleWith(MediaType) compatible} with the
* given one. Example: <pre><code class='java'>
* given one.
* <p>Example: <pre><code class='java'>
* // Check that actual is compatible with "text/plain"
* assertThat(mediaType).isCompatibleWith("text/plain");
* </code></pre>

View File

@@ -16,7 +16,6 @@
package org.springframework.test.json;
import java.lang.reflect.Array;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;
@@ -43,8 +42,9 @@ import org.springframework.util.StringUtils;
/**
* Base AssertJ {@link org.assertj.core.api.Assert assertions} that can be
* applied to a JSON value. In JSON, values must be one of the following data
* types:
* applied to a JSON value.
*
* <p>In JSON, values must be one of the following data types:
* <ul>
* <li>a {@linkplain #asString() string}</li>
* <li>a {@linkplain #asNumber() number}</li>
@@ -53,7 +53,7 @@ import org.springframework.util.StringUtils;
* <li>an {@linkplain #asMap() object} (JSON object)</li>
* <li>{@linkplain #isNull() null}</li>
* </ul>
* This base class offers direct access for each of those types as well as a
* This base class offers direct access for each of those types as well as
* conversion methods based on an optional {@link GenericHttpMessageConverter}.
*
* @author Stephane Nicoll
@@ -71,12 +71,14 @@ public abstract class AbstractJsonValueAssert<SELF extends AbstractJsonValueAsse
protected AbstractJsonValueAssert(@Nullable Object actual, Class<?> selfType,
@Nullable GenericHttpMessageConverter<Object> httpMessageConverter) {
super(actual, selfType);
this.httpMessageConverter = httpMessageConverter;
}
/**
* Verify that the actual value is a non-{@code null} {@link String}
* Verify that the actual value is a non-{@code null} {@link String},
* and return a new {@linkplain AbstractStringAssert assertion} object that
* provides dedicated {@code String} assertions for it.
*/
@@ -87,7 +89,7 @@ public abstract class AbstractJsonValueAssert<SELF extends AbstractJsonValueAsse
/**
* Verify that the actual value is a non-{@code null} {@link Number},
* usually an {@link Integer} or {@link Double} and return a new
* usually an {@link Integer} or {@link Double}, and return a new
* {@linkplain AbstractObjectAssert assertion} object for it.
*/
public AbstractObjectAssert<?, Number> asNumber() {
@@ -95,7 +97,7 @@ public abstract class AbstractJsonValueAssert<SELF extends AbstractJsonValueAsse
}
/**
* Verify that the actual value is a non-{@code null} {@link Boolean}
* Verify that the actual value is a non-{@code null} {@link Boolean},
* and return a new {@linkplain AbstractBooleanAssert assertion} object
* that provides dedicated {@code Boolean} assertions for it.
*/
@@ -104,9 +106,9 @@ public abstract class AbstractJsonValueAssert<SELF extends AbstractJsonValueAsse
}
/**
* Verify that the actual value is a non-{@code null} {@link Array}
* and return a new {@linkplain ObjectArrayAssert assertion} object
* that provides dedicated {@code Array} assertions for it.
* Verify that the actual value is a non-{@code null} array, and return a
* new {@linkplain ObjectArrayAssert assertion} object that provides dedicated
* array assertions for it.
*/
public ObjectArrayAssert<Object> asArray() {
List<?> list = castTo(List.class, "an array");
@@ -115,11 +117,12 @@ public abstract class AbstractJsonValueAssert<SELF extends AbstractJsonValueAsse
}
/**
* Verify that the actual value is a non-{@code null} JSON object and
* Verify that the actual value is a non-{@code null} JSON object, and
* return a new {@linkplain AbstractMapAssert assertion} object that
* provides dedicated assertions on individual elements of the
* object. The returned map assertion object uses the attribute name as the
* key, and the value can itself be any of the valid JSON values.
* object.
* <p>The returned map assertion object uses attribute names as the keys,
* and the values can be any of the valid JSON values.
*/
@SuppressWarnings("unchecked")
public AbstractMapAssert<?, Map<String, Object>, String, Object> asMap() {
@@ -138,7 +141,7 @@ public abstract class AbstractJsonValueAssert<SELF extends AbstractJsonValueAsse
/**
* Verify that the actual value can be converted to an instance of the
* given {@code target} and produce a new {@linkplain AbstractObjectAssert
* given {@code target}, and produce a new {@linkplain AbstractObjectAssert
* assertion} object narrowed to that type.
* @param target the {@linkplain Class type} to convert the actual value to
*/
@@ -150,7 +153,7 @@ public abstract class AbstractJsonValueAssert<SELF extends AbstractJsonValueAsse
/**
* Verify that the actual value can be converted to an instance of the
* given {@code target} and produce a new {@linkplain AbstractObjectAssert
* given {@code target}, and produce a new {@linkplain AbstractObjectAssert
* assertion} object narrowed to that type.
* @param target the {@linkplain ParameterizedTypeReference parameterized
* type} to convert the actual value to
@@ -162,9 +165,10 @@ public abstract class AbstractJsonValueAssert<SELF extends AbstractJsonValueAsse
}
/**
* Verify that the actual value is empty, that is a {@code null} scalar
* value or an empty list or map. Can also be used when the path is using a
* filter operator to validate that it dit not match.
* Verify that the actual value is empty: either a {@code null} scalar value
* or an empty list or map.
* <p>Can also be used when the path uses a filter operator to validate that
* it did not match.
*/
public SELF isEmpty() {
if (!ObjectUtils.isEmpty(this.actual)) {
@@ -174,10 +178,10 @@ public abstract class AbstractJsonValueAssert<SELF extends AbstractJsonValueAsse
}
/**
* Verify that the actual value is not empty, that is a non-{@code null}
* scalar value or a non-empty list or map. Can also be used when the path is
* using a filter operator to validate that it dit match at least one
* element.
* Verify that the actual value is not empty: either a non-{@code null}
* scalar value or a non-empty list or map.
* <p>Can also be used when the path uses a filter operator to validate that
* it did match at least one element.
*/
public SELF isNotEmpty() {
if (ObjectUtils.isEmpty(this.actual)) {
@@ -225,6 +229,7 @@ public abstract class AbstractJsonValueAssert<SELF extends AbstractJsonValueAsse
return ObjectUtils.nullSafeToString(StringUtils.quoteIfString(this.actual));
}
private static final class ValueProcessingFailed extends BasicErrorMessageFactory {
private ValueProcessingFailed(String prefix, String actualToString, String errorMessage) {

View File

@@ -22,9 +22,8 @@ import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
* JSON content usually created from a JSON tester. Generally used only to
* {@link AssertProvider provide} {@link JsonContentAssert} to AssertJ
* {@code assertThat} calls.
* JSON content which is generally used to {@link AssertProvider provide}
* {@link JsonContentAssert} to AssertJ {@code assertThat} calls.
*
* @author Phillip Webb
* @author Diego Berrueta
@@ -37,8 +36,9 @@ public final class JsonContent implements AssertProvider<JsonContentAssert> {
@Nullable
private final Class<?> resourceLoadClass;
/**
* Create a new {@link JsonContent} instance.
* Create a new {@code JsonContent} instance.
* @param json the actual JSON content
* @param resourceLoadClass the source class used to load resources
*/
@@ -48,6 +48,7 @@ public final class JsonContent implements AssertProvider<JsonContentAssert> {
this.resourceLoadClass = resourceLoadClass;
}
/**
* Use AssertJ's {@link org.assertj.core.api.Assertions#assertThat assertThat}
* instead.

View File

@@ -37,8 +37,8 @@ import org.springframework.util.function.ThrowingBiFunction;
/**
* AssertJ {@link org.assertj.core.api.Assert assertions} that can be applied
* to a {@link CharSequence} representation of a json document, mostly to
* compare the json document against a target, using {@linkplain JSONCompare
* to a {@link CharSequence} representation of a JSON document, mostly to
* compare the JSON document against a target, using {@linkplain JSONCompare
* JSON Assert}.
*
* @author Phillip Webb
@@ -57,7 +57,7 @@ public class JsonContentAssert extends AbstractAssert<JsonContentAssert, CharSeq
* relative to the given {@code resourceLoadClass}, using the given
* {@code charset}.
* @param json the actual JSON content
* @param resourceLoadClass the source class used to load resources
* @param resourceLoadClass the class used to load resources
* @param charset the charset of the JSON resources
*/
public JsonContentAssert(@Nullable CharSequence json, @Nullable Class<?> resourceLoadClass,
@@ -71,7 +71,7 @@ public class JsonContentAssert extends AbstractAssert<JsonContentAssert, CharSeq
* Create a new {@link JsonContentAssert} instance that will load resources
* relative to the given {@code resourceLoadClass}, using {@code UTF-8}.
* @param json the actual JSON content
* @param resourceLoadClass the source class used to load resources
* @param resourceLoadClass the class used to load resources
*/
public JsonContentAssert(@Nullable CharSequence json, @Nullable Class<?> resourceLoadClass) {
this(json, resourceLoadClass, null);
@@ -343,7 +343,6 @@ public class JsonContentAssert extends AbstractAssert<JsonContentAssert, CharSeq
private JSONCompareResult compareForNull(@Nullable CharSequence expectedJson) {
JSONCompareResult result = new JSONCompareResult();
result.passed();
if (expectedJson != null) {
result.fail("Expected null JSON");
}
@@ -352,14 +351,14 @@ public class JsonContentAssert extends AbstractAssert<JsonContentAssert, CharSeq
private JsonContentAssert assertNotFailed(JSONCompareResult result) {
if (result.failed()) {
failWithMessage("JSON Comparison failure: %s", result.getMessage());
failWithMessage("JSON comparison failure: %s", result.getMessage());
}
return this;
}
private JsonContentAssert assertNotPassed(JSONCompareResult result) {
if (result.passed()) {
failWithMessage("JSON Comparison failure: %s", result.getMessage());
failWithMessage("JSON comparison failure: %s", result.getMessage());
}
return this;
}

View File

@@ -42,20 +42,23 @@ class JsonLoader {
private final Charset charset;
JsonLoader(@Nullable Class<?> resourceLoadClass, @Nullable Charset charset) {
this.resourceLoadClass = resourceLoadClass;
this.charset = (charset != null ? charset : StandardCharsets.UTF_8);
}
@Nullable
String getJson(@Nullable CharSequence source) {
if (source == null) {
return null;
}
if (source.toString().endsWith(".json")) {
return getJson(new ClassPathResource(source.toString(), this.resourceLoadClass));
String string = source.toString();
if (string.endsWith(".json")) {
return getJson(new ClassPathResource(string, this.resourceLoadClass));
}
return source.toString();
return string;
}
String getJson(Resource source) {

View File

@@ -31,7 +31,7 @@ import org.springframework.util.Assert;
/**
* AssertJ {@link org.assertj.core.api.Assert assertions} that can be applied
* to a {@link CharSequence} representation of a json document using
* to a {@link CharSequence} representation of a JSON document using
* {@linkplain JsonPath JSON path}.
*
* @author Stephane Nicoll
@@ -41,17 +41,21 @@ public class JsonPathAssert extends AbstractAssert<JsonPathAssert, CharSequence>
private static final Failures failures = Failures.instance();
@Nullable
private final GenericHttpMessageConverter<Object> jsonMessageConverter;
public JsonPathAssert(CharSequence json,
@Nullable GenericHttpMessageConverter<Object> jsonMessageConverter) {
super(json, JsonPathAssert.class);
this.jsonMessageConverter = jsonMessageConverter;
}
/**
* Verify that the given JSON {@code path} is present and extract the JSON
* Verify that the given JSON {@code path} is present, and extract the JSON
* value for further {@linkplain JsonPathValueAssert assertions}.
* @param path the {@link JsonPath} expression
* @see #hasPathSatisfying(String, Consumer)
@@ -158,8 +162,9 @@ public class JsonPathAssert extends AbstractAssert<JsonPathAssert, CharSequence>
static final class JsonPathNotExpected extends BasicErrorMessageFactory {
private JsonPathNotExpected(String actual, String path) {
super("%nExpecting:%n %s%nTo not match JSON path:%n %s%n", actual, path);
super("%nExpecting:%n %s%nNot to match JSON path:%n %s%n", actual, path);
}
}
}
}

View File

@@ -29,14 +29,14 @@ import org.springframework.lang.Nullable;
* @author Stephane Nicoll
* @since 6.2
*/
public class JsonPathValueAssert
extends AbstractJsonValueAssert<JsonPathValueAssert> {
public class JsonPathValueAssert extends AbstractJsonValueAssert<JsonPathValueAssert> {
private final String expression;
JsonPathValueAssert(@Nullable Object actual, String expression,
@Nullable GenericHttpMessageConverter<Object> httpMessageConverter) {
super(actual, JsonPathValueAssert.class, httpMessageConverter);
this.expression = expression;
}
@@ -45,4 +45,5 @@ public class JsonPathValueAssert
protected String getExpectedErrorMessagePrefix() {
return "Expected value at JSON path \"%s\":".formatted(this.expression);
}
}

View File

@@ -44,6 +44,7 @@ public abstract class AbstractBindingResultAssert<SELF extends AbstractBindingRe
private final String name;
protected AbstractBindingResultAssert(String name, BindingResult bindingResult, Class<?> selfType) {
super(bindingResult, selfType);
this.name = name;
@@ -51,7 +52,7 @@ public abstract class AbstractBindingResultAssert<SELF extends AbstractBindingRe
}
/**
* Verify that the total number of errors is equal to the given one.
* Verify that the total number of errors is equal to the expected value.
* @param expected the expected number of errors
*/
public SELF hasErrorsCount(int expected) {
@@ -73,7 +74,7 @@ public abstract class AbstractBindingResultAssert<SELF extends AbstractBindingRe
/**
* Verify that the actual binding result contains <em>only</em> fields in
* error with the given {@code fieldNames}, and nothing else.
* @param fieldNames the exhaustive list of field name that should be in error
* @param fieldNames the exhaustive list of field names that should be in error
*/
public SELF hasOnlyFieldErrors(String... fieldNames) {
assertThat(fieldErrorNames()).containsOnly(fieldNames);

View File

@@ -70,7 +70,7 @@ public class UriAssert extends AbstractStringAssert<UriAssert> {
* </code></pre>
* @param uriPattern the pattern that is expected to match
*/
public UriAssert matchPattern(String uriPattern) {
public UriAssert matchesPattern(String uriPattern) {
Assertions.assertThat(pathMatcher.isPattern(uriPattern))
.withFailMessage("'%s' is not an Ant-style path pattern", uriPattern).isTrue();
Assertions.assertThat(pathMatcher.match(uriPattern, this.actual))

View File

@@ -35,7 +35,7 @@ import org.springframework.web.context.request.async.DeferredResult;
/**
* Base AssertJ {@link org.assertj.core.api.Assert assertions} that can be
* applied to a {@link HttpServletRequest}.
* applied to an {@link HttpServletRequest}.
*
* @author Stephane Nicoll
* @since 6.2
@@ -70,7 +70,7 @@ public abstract class AbstractHttpServletRequestAssert<SELF extends AbstractHttp
/**
* Return a new {@linkplain MapAssert assertion} object that uses the request
* attributes as the object to test, with values mapped by attribute name.
* Examples: <pre><code class='java'>
* <p>Example: <pre><code class='java'>
* // Check for the presence of a request attribute named "attributeName":
* assertThat(request).attributes().containsKey("attributeName");
* </code></pre>
@@ -82,7 +82,7 @@ public abstract class AbstractHttpServletRequestAssert<SELF extends AbstractHttp
/**
* Return a new {@linkplain MapAssert assertion} object that uses the session
* attributes as the object to test, with values mapped by attribute name.
* Examples: <pre><code class='java'>
* <p>Example: <pre><code class='java'>
* // Check for the presence of a session attribute named "username":
* assertThat(request).sessionAttributes().containsKey("username");
* </code></pre>
@@ -92,8 +92,8 @@ public abstract class AbstractHttpServletRequestAssert<SELF extends AbstractHttp
}
/**
* Verify that whether asynchronous processing started, usually as a result
* of a controller method returning {@link Callable} or {@link DeferredResult}.
* Verify whether asynchronous processing has started, usually as a result
* of a controller method returning a {@link Callable} or {@link DeferredResult}.
* <p>The test will await the completion of a {@code Callable} so that
* {@link MvcResultAssert#asyncResult()} can be used to assert the resulting
* value.
@@ -104,7 +104,7 @@ public abstract class AbstractHttpServletRequestAssert<SELF extends AbstractHttp
*/
public SELF hasAsyncStarted(boolean started) {
Assertions.assertThat(this.actual.isAsyncStarted())
.withFailMessage("Async expected to %s started", (started ? "have" : "not have"))
.withFailMessage("Async expected %sto have started", (started ? "" : "not "))
.isEqualTo(started);
return this.myself;
}

View File

@@ -36,8 +36,8 @@ import org.springframework.util.function.SingletonSupplier;
/**
* Base AssertJ {@link org.assertj.core.api.Assert assertions} that can be
* applied to any object that provides an {@link HttpServletResponse}. This
* allows to provide direct access to response assertions while providing
* access to a different top-level object.
* provides direct access to response assertions while also providing access to
* a different top-level object.
*
* @author Stephane Nicoll
* @since 6.2
@@ -60,21 +60,22 @@ public abstract class AbstractHttpServletResponseAssert<R extends HttpServletRes
}
/**
* Provide the response to use if it is available. Throw an
* {@link AssertionError} if the request has failed to process and the
* response is not available.
* Provide the response to use if it is available.
* <p>Throws an {@link AssertionError} if the request has failed to process,
* and the response is not available.
* @return the response to use
*/
protected abstract R getResponse();
/**
* Return a new {@linkplain HttpHeadersAssert assertion} object that uses
* the {@link HttpHeaders} as the object to test. The return assertion
* {@link HttpHeaders} as the object to test. The returned assertion
* object provides all the regular {@linkplain AbstractMapAssert map
* assertions}, with headers mapped by header name.
* Examples: <pre><code class='java'>
* // Check for the presence of the Accept header:
* assertThat(response).headers().containsHeader(HttpHeaders.ACCEPT);
*
* // Check for the absence of the Content-Length header:
* assertThat(response).headers().doesNotContainsHeader(HttpHeaders.CONTENT_LENGTH);
* </code></pre>

View File

@@ -33,6 +33,4 @@ public abstract class AbstractMockHttpServletRequestAssert<SELF extends Abstract
super(request, selfType);
}
}

View File

@@ -47,12 +47,13 @@ public abstract class AbstractMockHttpServletResponseAssert<SELF extends Abstrac
/**
* Return a new {@linkplain ResponseBodyAssert assertion} object that uses
* the response body as the object to test. The return assertion object
* the response body as the object to test. The returned assertion object
* provides access to the raw byte array, a String value decoded using the
* response's character encoding, and dedicated json testing support.
* Examples: <pre><code class='java'>
* response's character encoding, and dedicated JSON testing support.
* <p>Examples: <pre><code class='java'>
* // Check that the response body is equal to "Hello World":
* assertThat(response).body().isEqualTo("Hello World");
*
* // Check that the response body is strictly equal to the content of "test.json":
* assertThat(response).body().json().isStrictlyEqualToJson("test.json");
* </code></pre>
@@ -65,8 +66,8 @@ public abstract class AbstractMockHttpServletResponseAssert<SELF extends Abstrac
/**
* Return a new {@linkplain UriAssert assertion} object that uses the
* forwarded URL as the object to test. If a simple equality check is
* required consider using {@link #hasForwardedUrl(String)} instead.
* Example: <pre><code class='java'>
* required, consider using {@link #hasForwardedUrl(String)} instead.
* <p>Example: <pre><code class='java'>
* // Check that the forwarded URL starts with "/orders/":
* assertThat(response).forwardedUrl().matchPattern("/orders/*);
* </code></pre>
@@ -78,8 +79,8 @@ public abstract class AbstractMockHttpServletResponseAssert<SELF extends Abstrac
/**
* Return a new {@linkplain UriAssert assertion} object that uses the
* redirected URL as the object to test. If a simple equality check is
* required consider using {@link #hasRedirectedUrl(String)} instead.
* Example: <pre><code class='java'>
* required, consider using {@link #hasRedirectedUrl(String)} instead.
* <p>Example: <pre><code class='java'>
* // Check that the redirected URL starts with "/orders/":
* assertThat(response).redirectedUrl().matchPattern("/orders/*);
* </code></pre>

View File

@@ -38,7 +38,7 @@ import org.springframework.util.Assert;
import org.springframework.web.context.WebApplicationContext;
/**
* {@link MockMvc} variant that tests Spring MVC exchanges and provide fluent
* {@link MockMvc} variant that tests Spring MVC exchanges and provides fluent
* assertions using {@link org.assertj.core.api.Assertions AssertJ}.
*
* <p>A main difference with {@link MockMvc} is that an unresolved exception
@@ -47,7 +47,7 @@ import org.springframework.web.context.WebApplicationContext;
* exception}.
*
* <p>{@link AssertableMockMvc} can be configured with a list of
* {@linkplain HttpMessageConverter HttpMessageConverters} to allow response
* {@linkplain HttpMessageConverter message converters} to allow the response
* body to be deserialized, rather than asserting on the raw values.
*
* @author Stephane Nicoll
@@ -71,8 +71,8 @@ public final class AssertableMockMvc {
}
/**
* Create a new {@link AssertableMockMvc} instance that delegates to the
* given {@link MockMvc}.
* Create a {@link AssertableMockMvc} instance that delegates to the given
* {@link MockMvc} instance.
* @param mockMvc the MockMvc instance to delegate calls to
*/
public static AssertableMockMvc create(MockMvc mockMvc) {
@@ -80,7 +80,7 @@ public final class AssertableMockMvc {
}
/**
* Create a {@link AssertableMockMvc} instance using the given, fully
* Create an {@link AssertableMockMvc} instance using the given, fully
* initialized (i.e., <em>refreshed</em>) {@link WebApplicationContext}. The
* given {@code customizations} are applied to the {@link DefaultMockMvcBuilder}
* that ultimately creates the underlying {@link MockMvc} instance.
@@ -88,7 +88,7 @@ public final class AssertableMockMvc {
* is required, use {@link #from(WebApplicationContext)}.
* @param applicationContext the application context to detect the Spring
* MVC infrastructure and application controllers from
* @param customizations the function that creates a {@link MockMvc}
* @param customizations a function that creates a {@link MockMvc}
* instance based on a {@link DefaultMockMvcBuilder}.
* @see MockMvcBuilders#webAppContextSetup(WebApplicationContext)
*/
@@ -101,10 +101,10 @@ public final class AssertableMockMvc {
}
/**
* Shortcut to create a {@link AssertableMockMvc} instance using the given,
* Shortcut to create an {@link AssertableMockMvc} instance using the given,
* fully initialized (i.e., <em>refreshed</em>) {@link WebApplicationContext}.
* <p>Consider using {@link #from(WebApplicationContext, Function)} if
* further customizations of the underlying {@link MockMvc} instance is
* further customization of the underlying {@link MockMvc} instance is
* required.
* @param applicationContext the application context to detect the Spring
* MVC infrastructure and application controllers from
@@ -115,17 +115,18 @@ public final class AssertableMockMvc {
}
/**
* Create a {@link AssertableMockMvc} instance by registering one or more
* Create an {@link AssertableMockMvc} instance by registering one or more
* {@code @Controller} instances and configuring Spring MVC infrastructure
* programmatically.
* <p>This allows full control over the instantiation and initialization of
* controllers and their dependencies, similar to plain unit tests while
* also making it possible to test one controller at a time.
* @param controllers one or more {@code @Controller} instances to test
* (specified {@code Class} will be turned into instance)
* @param customizations the function that creates a {@link MockMvc}
* instance based on a {@link StandaloneMockMvcBuilder}, typically to
* configure the Spring MVC infrastructure
* @param controllers one or more {@code @Controller} instances or
* {@code @Controller} types to test; a type ({@code Class}) will be turned
* into an instance
* @param customizations a function that creates a {@link MockMvc} instance
* based on a {@link StandaloneMockMvcBuilder}, typically to configure the
* Spring MVC infrastructure
* @see MockMvcBuilders#standaloneSetup(Object...)
*/
public static AssertableMockMvc of(Collection<?> controllers,
@@ -136,15 +137,16 @@ public final class AssertableMockMvc {
}
/**
* Shortcut to create a {@link AssertableMockMvc} instance by registering
* Shortcut to create an {@link AssertableMockMvc} instance by registering
* one or more {@code @Controller} instances.
* <p>The minimum infrastructure required by the
* {@link org.springframework.web.servlet.DispatcherServlet DispatcherServlet}
* to serve requests with annotated controllers is created. Consider using
* {@link #of(Collection, Function)} if additional configuration of the MVC
* infrastructure is required.
* @param controllers one or more {@code @Controller} instances to test
* (specified {@code Class} will be turned into instance)
* @param controllers one or more {@code @Controller} instances or
* {@code @Controller} types to test; a type ({@code Class}) will be turned
* into an instance
* @see MockMvcBuilders#standaloneSetup(Object...)
*/
public static AssertableMockMvc of(Object... controllers) {
@@ -153,9 +155,10 @@ public final class AssertableMockMvc {
/**
* Return a new {@link AssertableMockMvc} instance using the specified
* {@link HttpMessageConverter}. If none are specified, only basic assertions
* on the response body can be performed. Consider registering a suitable
* JSON converter for asserting data structure.
* {@linkplain HttpMessageConverter message converters}.
* <p>If none are specified, only basic assertions on the response body can
* be performed. Consider registering a suitable JSON converter for asserting
* against JSON data structures.
* @param httpMessageConverters the message converters to use
* @return a new instance using the specified converters
*/
@@ -169,7 +172,7 @@ public final class AssertableMockMvc {
* <p>Use static methods of {@link MockMvcRequestBuilders} to prepare the
* request, wrapping the invocation in {@code assertThat}. The following
* asserts that a {@linkplain MockMvcRequestBuilders#get(URI) GET} request
* against "/greet" has an HTTP status code 200 (OK), and a simple body:
* against "/greet" has an HTTP status code 200 (OK) and a simple body:
* <pre><code class='java'>assertThat(mvc.perform(get("/greet")))
* .hasStatusOk()
* .body().asString().isEqualTo("Hello");
@@ -177,7 +180,7 @@ public final class AssertableMockMvc {
* <p>Contrary to {@link MockMvc#perform(RequestBuilder)}, this does not
* throw an exception if the request fails with an unresolved exception.
* Rather, the result provides the exception, if any. Assuming that a
* {@linkplain MockMvcRequestBuilders#post(URI) POST} request against
* {@link MockMvcRequestBuilders#post(URI) POST} request against
* {@code /boom} throws an {@code IllegalStateException}, the following
* asserts that the invocation has indeed failed with the expected error
* message:
@@ -185,7 +188,6 @@ public final class AssertableMockMvc {
* .unresolvedException().isInstanceOf(IllegalStateException.class)
* .hasMessage("Expected");
* </code></pre>
* <p>
* @param requestBuilder used to prepare the request to execute;
* see static factory methods in
* {@link org.springframework.test.web.servlet.request.MockMvcRequestBuilders}

View File

@@ -24,13 +24,13 @@ import org.springframework.test.web.servlet.MvcResult;
/**
* A {@link MvcResult} that additionally supports AssertJ style assertions.
*
* <p>Can be in two distinct states:
* <p>Can be in one of two distinct states:
* <ol>
* <li>The request processed successfully, and {@link #getUnresolvedException()}
* is therefore {@code null}.</li>
* <li>The request failed unexpectedly with {@link #getUnresolvedException()}
* providing more information about the error. Any attempt to access a
* member of the result fails with an exception.</li>
* providing more information about the error. Any attempt to access a member of
* the result fails with an exception.</li>
* </ol>
*
* @author Stephane Nicoll

View File

@@ -58,8 +58,7 @@ public class CookieMapAssert extends AbstractMapAssert<CookieMapAssert, Map<Stri
}
/**
* Verify that the actual cookies contain the cookies with the given
* {@code names}.
* Verify that the actual cookies contain cookies with the given {@code names}.
* @param names the names of expected cookies
* @see #containsKeys
*/
@@ -68,8 +67,8 @@ public class CookieMapAssert extends AbstractMapAssert<CookieMapAssert, Map<Stri
}
/**
* Verify that the actual cookies do not contain a cookie with the
* given {@code name}.
* Verify that the actual cookies do not contain a cookie with the given
* {@code name}.
* @param name the name of a cookie that should not be present
* @see #doesNotContainKey
*/
@@ -78,8 +77,8 @@ public class CookieMapAssert extends AbstractMapAssert<CookieMapAssert, Map<Stri
}
/**
* Verify that the actual cookies do not contain any of the cookies with
* the given {@code names}.
* Verify that the actual cookies do not contain any cookies with the given
* {@code names}.
* @param names the names of cookies that should not be present
* @see #doesNotContainKeys
*/
@@ -88,9 +87,8 @@ public class CookieMapAssert extends AbstractMapAssert<CookieMapAssert, Map<Stri
}
/**
* Verify that the actual cookies contain a cookie with the given
* {@code name} that satisfy given {@code cookieRequirements}.
* the specified names.
* Verify that the actual cookies contain a cookie with the given {@code name}
* that satisfies the given {@code cookieRequirements}.
* @param name the name of an expected cookie
* @param cookieRequirements the requirements for the cookie
*/
@@ -99,9 +97,8 @@ public class CookieMapAssert extends AbstractMapAssert<CookieMapAssert, Map<Stri
}
/**
* Verify that the actual cookies contain a cookie with the given
* {@code name} whose {@linkplain Cookie#getValue() value} is equal to the
* given one.
* Verify that the actual cookies contain a cookie with the given {@code name}
* whose {@linkplain Cookie#getValue() value} is equal to the expected value.
* @param name the name of the cookie
* @param expected the expected value of the cookie
*/
@@ -111,9 +108,8 @@ public class CookieMapAssert extends AbstractMapAssert<CookieMapAssert, Map<Stri
}
/**
* Verify that the actual cookies contain a cookie with the given
* {@code name} whose {@linkplain Cookie#getMaxAge() max age} is equal to
* the given one.
* Verify that the actual cookies contain a cookie with the given {@code name}
* whose {@linkplain Cookie#getMaxAge() max age} is equal to the expected value.
* @param name the name of the cookie
* @param expected the expected max age of the cookie
*/
@@ -123,9 +119,8 @@ public class CookieMapAssert extends AbstractMapAssert<CookieMapAssert, Map<Stri
}
/**
* Verify that the actual cookies contain a cookie with the given
* {@code name} whose {@linkplain Cookie#getPath() path} is equal to
* the given one.
* Verify that the actual cookies contain a cookie with the given {@code name}
* whose {@linkplain Cookie#getPath() path} is equal to the expected value.
* @param name the name of the cookie
* @param expected the expected path of the cookie
*/
@@ -135,11 +130,10 @@ public class CookieMapAssert extends AbstractMapAssert<CookieMapAssert, Map<Stri
}
/**
* Verify that the actual cookies contain a cookie with the given
* {@code name} whose {@linkplain Cookie#getDomain() domain} is equal to
* the given one.
* Verify that the actual cookies contain a cookie with the given {@code name}
* whose {@linkplain Cookie#getDomain() domain} is equal to the expected value.
* @param name the name of the cookie
* @param expected the expected path of the cookie
* @param expected the expected domain of the cookie
*/
public CookieMapAssert hasDomain(String name, String expected) {
return hasCookieSatisfying(name, cookie ->
@@ -147,9 +141,9 @@ public class CookieMapAssert extends AbstractMapAssert<CookieMapAssert, Map<Stri
}
/**
* Verify that the actual cookies contain a cookie with the given
* {@code name} whose {@linkplain Cookie#getSecure() secure flag} is equal
* to the given one.
* Verify that the actual cookies contain a cookie with the given {@code name}
* whose {@linkplain Cookie#getSecure() secure flag} is equal to the expected
* value.
* @param name the name of the cookie
* @param expected whether the cookie is secure
*/
@@ -159,9 +153,9 @@ public class CookieMapAssert extends AbstractMapAssert<CookieMapAssert, Map<Stri
}
/**
* Verify that the actual cookies contain a cookie with the given
* {@code name} whose {@linkplain Cookie#isHttpOnly() http only flag} is
* equal to the given one.
* Verify that the actual cookies contain a cookie with the given {@code name}
* whose {@linkplain Cookie#isHttpOnly() http only flag} is equal to the
* expected value.
* @param name the name of the cookie
* @param expected whether the cookie is http only
*/

View File

@@ -46,9 +46,9 @@ public class HandlerResultAssert extends AbstractObjectAssert<HandlerResultAsser
/**
* Return a new {@linkplain MethodAssert assertion} object that uses
* the {@link Method} that handles the request as the object to test.
* Verify first that the handler is a {@linkplain #isMethodHandler() method
* handler}.
* Example: <pre><code class='java'>
* <p>Verifies first that the handler is a {@linkplain #isMethodHandler()
* method handler}.
* <p>Example: <pre><code class='java'>
* // Check that a GET to "/greet" is invoked on a "handleGreet" method name
* assertThat(mvc.perform(get("/greet")).handler().method().hasName("sayGreet");
* </code></pre>
@@ -67,14 +67,15 @@ public class HandlerResultAssert extends AbstractObjectAssert<HandlerResultAsser
/**
* Verify that the handler is managed by the given {@code handlerMethod}.
* This creates a "mock" for the given {@code controllerType} and record the
* method invocation in the {@code handlerMethod}. The arguments used by the
* target method invocation can be {@code null} as the purpose of the mock
* <p>This creates a "mock" for the given {@code controllerType} and records
* the method invocation in the {@code handlerMethod}. The arguments used by
* the target method invocation can be {@code null} as the purpose of the mock
* is to identify the method that was invoked.
* Example: <pre><code class='java'>
* <p>Example: <pre><code class='java'>
* // If the method has a return type, you can return the result of the invocation
* assertThat(mvc.perform(get("/greet")).handler().isInvokedOn(
* GreetController.class, controller -> controller.sayGreet());
*
* // If the method has a void return type, the controller should be returned
* assertThat(mvc.perform(post("/persons/")).handler().isInvokedOn(
* PersonController.class, controller -> controller.createPerson(null, null));
@@ -95,7 +96,7 @@ public class HandlerResultAssert extends AbstractObjectAssert<HandlerResultAsser
/**
* Verify that the handler is of the given {@code type}. For a controller
* method, this is the type of the controller.
* Example: <pre><code class='java'>
* <p>Example: <pre><code class='java'>
* // Check that a GET to "/greet" is managed by GreetController
* assertThat(mvc.perform(get("/greet")).handler().hasType(GreetController.class);
* </code></pre>

View File

@@ -51,7 +51,7 @@ public class ModelAssert extends AbstractMapAssert<ModelAssert, Map<String, Obje
* Return a new {@linkplain AbstractBindingResultAssert assertion} object
* that uses the {@link BindingResult} with the given {@code name} as the
* object to test.
* Examples: <pre><code class='java'>
* <p>Example: <pre><code class='java'>
* // Check that the "person" attribute in the model has 2 errors:
* assertThat(...).model().extractingBindingResult("person").hasErrorsCount(2);
* </code></pre>
@@ -85,23 +85,23 @@ public class ModelAssert extends AbstractMapAssert<ModelAssert, Map<String, Obje
}
/**
* Verify that the actual model contain the attributes with the given
* {@code names}, and that these attributes have each at least one error.
* Verify that the actual model contains the attributes with the given
* {@code names}, and that each of these attributes has each at least one error.
* @param names the expected names of attributes with errors
*/
public ModelAssert hasAttributeErrors(String... names) {
return assertAttributes(names, BindingResult::hasErrors,
"to have attribute errors for", "these attributes do not have any error");
"to have attribute errors for", "these attributes do not have any errors");
}
/**
* Verify that the actual model contain the attributes with the given
* {@code names}, and that these attributes do not have any error.
* Verify that the actual model contains the attributes with the given
* {@code names}, and that none of these attributes has an error.
* @param names the expected names of attributes without errors
*/
public ModelAssert doesNotHaveAttributeErrors(String... names) {
return assertAttributes(names, Predicate.not(BindingResult::hasErrors),
"to have attribute without errors for", "these attributes have at least an error");
"to have attribute without errors for", "these attributes have at least one error");
}
private ModelAssert assertAttributes(String[] names, Predicate<BindingResult> condition,

View File

@@ -102,7 +102,7 @@ public class MvcResultAssert extends AbstractMockHttpServletResponseAssert<MvcRe
* Return a new {@linkplain HandlerResultAssert assertion} object that uses
* the handler as the object to test. For a method invocation on a
* controller, this is relative method handler
* Example: <pre><code class='java'>
* <p>Example: <pre><code class='java'>
* // Check that a GET to "/greet" is invoked on a "handleGreet" method name
* assertThat(mvc.perform(get("/greet")).handler().method().hasName("sayGreet");
* </code></pre>

View File

@@ -62,12 +62,14 @@ public class ResponseBodyAssert extends AbstractByteArrayAssert<ResponseBodyAsse
}
/**
* Return a new {@linkplain JsonContentAssert assertion} object that
* provides {@linkplain org.skyscreamer.jsonassert.JSONCompareMode JSON
* assert} comparison to expected json input that can be loaded from the
* classpath. Only absolute locations are supported, consider using
* {@link #json(Class)} to load json documents relative to a given class.
* Example: <pre><code class='java'>
* Return a new {@linkplain JsonContentAssert assertion} object that provides
* support for {@linkplain org.skyscreamer.jsonassert.JSONCompareMode JSON
* assert} comparisons against expected JSON input which can be loaded from
* the classpath.
* <p>This method only supports absolute locations for JSON documents loaded
* from the classpath. Consider using {@link #json(Class)} to load JSON
* documents relative to a given class.
* <p>Example: <pre><code class='java'>
* // Check that the response is strictly equal to the content of
* // "/com/acme/web/person/person-created.json":
* assertThat(...).body().json()
@@ -79,18 +81,19 @@ public class ResponseBodyAssert extends AbstractByteArrayAssert<ResponseBodyAsse
}
/**
* Return a new {@linkplain JsonContentAssert assertion} object that
* provides {@linkplain org.skyscreamer.jsonassert.JSONCompareMode JSON
* assert} comparison to expected json input that can be loaded from the
* classpath. Documents can be absolute using a leading slash, or relative
* to the given {@code resourceLoadClass}.
* Example: <pre><code class='java'>
* // Check that the response is strictly equal to the content of
* // the specified file:
* Return a new {@linkplain JsonContentAssert assertion} object that provides
* support for {@linkplain org.skyscreamer.jsonassert.JSONCompareMode JSON
* assert} comparisons against expected JSON input which can be loaded from
* the classpath.
* <p>Locations for JSON documents can be absolute using a leading slash, or
* relative to the given {@code resourceLoadClass}.
* <p>Example: <pre><code class='java'>
* // Check that the response is strictly equal to the content of the
* // specified file located in the same package as the PersonController:
* assertThat(...).body().json(PersonController.class)
* .isStrictlyEqualToJson("person-created.json");
* </code></pre>
* @param resourceLoadClass the class used to load relative json documents
* @param resourceLoadClass the class used to load relative JSON documents
* @see ClassPathResource#ClassPathResource(String, Class)
*/
public JsonContentAssert json(@Nullable Class<?> resourceLoadClass) {
@@ -98,8 +101,8 @@ public class ResponseBodyAssert extends AbstractByteArrayAssert<ResponseBodyAsse
}
/**
* Verifies that the response body is equal to the given {@link String}.
* <p>Convert the actual byte array to a String using the character encoding
* Verify that the response body is equal to the given {@link String}.
* <p>Converts the actual byte array to a String using the character encoding
* of the {@link HttpServletResponse}.
* @param expected the expected content of the response body
* @see #asString()
@@ -110,8 +113,8 @@ public class ResponseBodyAssert extends AbstractByteArrayAssert<ResponseBodyAsse
}
/**
* Override that uses the character encoding of {@link HttpServletResponse} to
* convert the byte[] to a String, rather than the platform's default charset.
* Override that uses the character encoding of the {@link HttpServletResponse}
* to convert the byte[] to a String, rather than the platform's default charset.
*/
@Override
public AbstractStringAssert<?> asString() {