From 5567d14700e9b5ad0caf6e093deca06c90fa2b7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Nicoll?= Date: Mon, 6 May 2024 15:11:30 +0200 Subject: [PATCH] Move response body directly in AbstractMockHttpServletResponseAssert This commit removes ResponseBodyAssert and rather offers first-class access support for the response body at the root level using bodyText(), bodyJson(), and body(). This avoids a double navigation to assert the response body. See gh-32712 --- .../test/json/AbstractJsonContentAssert.java | 49 +++++-- .../test/json/JsonContent.java | 2 +- .../test/json/JsonContentAssert.java | 14 +- ...AbstractMockHttpServletResponseAssert.java | 75 ++++++++-- .../servlet/assertj/ResponseBodyAssert.java | 130 ------------------ .../json/AbstractJsonContentAssertTests.java | 28 ++-- ...actMockHttpServletResponseAssertTests.java | 78 ++++++++--- .../AssertableMockMvcIntegrationTests.java | 6 +- .../assertj/AssertableMockMvcTests.java | 22 +-- .../assertj/ResponseBodyAssertTests.java | 88 ------------ 10 files changed, 193 insertions(+), 299 deletions(-) delete mode 100644 spring-test/src/main/java/org/springframework/test/web/servlet/assertj/ResponseBodyAssert.java delete mode 100644 spring-test/src/test/java/org/springframework/test/web/servlet/assertj/ResponseBodyAssertTests.java diff --git a/spring-test/src/main/java/org/springframework/test/json/AbstractJsonContentAssert.java b/spring-test/src/main/java/org/springframework/test/json/AbstractJsonContentAssert.java index 45b7e839209..4c1771de2cb 100644 --- a/spring-test/src/main/java/org/springframework/test/json/AbstractJsonContentAssert.java +++ b/spring-test/src/main/java/org/springframework/test/json/AbstractJsonContentAssert.java @@ -52,7 +52,10 @@ import org.springframework.util.function.ThrowingBiFunction; * assertions} on the value. * *

Also support comparing the JSON document against a target, using - * {@linkplain JSONCompare JSON Assert}. + * {@linkplain JSONCompare JSON Assert}. Resources that are loaded from + * the classpath can be relative if a {@linkplain #withResourceLoadClass(Class) + * class} is provided. By default, {@code UTF-8} is used to load resources + * but this can be overridden using {@link #withCharset(Charset)}. * * @author Stephane Nicoll * @author Phillip Webb @@ -71,28 +74,27 @@ public abstract class AbstractJsonContentAssert jsonMessageConverter; - private final JsonLoader jsonLoader; + @Nullable + private Class resourceLoadClass; + + @Nullable + private Charset charset; + + private JsonLoader jsonLoader; /** * Create an assert for the given JSON document. *

Path can be converted to a value object using the given * {@linkplain GenericHttpMessageConverter json message converter}. - *

Resources to match can be loaded relative to the given - * {@code resourceLoadClass}. If not specified, resources must always be - * absolute. A specific {@link Charset} can be provided if {@code UTF-8} is - * not suitable. * @param json the JSON document to assert * @param jsonMessageConverter the converter to use - * @param resourceLoadClass the class used to load resources - * @param charset the charset of the JSON resources * @param selfType the implementation type of this assert */ protected AbstractJsonContentAssert(@Nullable String json, - @Nullable GenericHttpMessageConverter jsonMessageConverter, @Nullable Class resourceLoadClass, - @Nullable Charset charset, Class selfType) { + @Nullable GenericHttpMessageConverter jsonMessageConverter, Class selfType) { super(json, selfType); this.jsonMessageConverter = jsonMessageConverter; - this.jsonLoader = new JsonLoader(resourceLoadClass, charset); + this.jsonLoader = new JsonLoader(null, null); as("JSON content"); } @@ -376,6 +378,31 @@ public abstract class AbstractJsonContentAssert resourceLoadClass) { + this.resourceLoadClass = resourceLoadClass; + this.jsonLoader = new JsonLoader(resourceLoadClass, this.charset); + return this.myself; + } + + /** + * Override the {@link Charset} to use to load resources. By default, + * resources are loaded using {@code UTF-8}. + * @param charset the charset to use, or {@code null} to use the default + */ + public SELF withCharset(@Nullable Charset charset) { + this.charset = charset; + this.jsonLoader = new JsonLoader(this.resourceLoadClass, charset); + return this.myself; + } + private JSONCompareResult compare(@Nullable CharSequence expectedJson, JSONCompareMode compareMode) { return compare(this.actual, expectedJson, (actualJsonString, expectedJsonString) -> diff --git a/spring-test/src/main/java/org/springframework/test/json/JsonContent.java b/spring-test/src/main/java/org/springframework/test/json/JsonContent.java index f36e7ddd7f5..c801a5fa5d6 100644 --- a/spring-test/src/main/java/org/springframework/test/json/JsonContent.java +++ b/spring-test/src/main/java/org/springframework/test/json/JsonContent.java @@ -55,7 +55,7 @@ public final class JsonContent implements AssertProvider { */ @Override public JsonContentAssert assertThat() { - return new JsonContentAssert(this.json, null, this.resourceLoadClass, null); + return new JsonContentAssert(this.json, null).withResourceLoadClass(this.resourceLoadClass); } /** diff --git a/spring-test/src/main/java/org/springframework/test/json/JsonContentAssert.java b/spring-test/src/main/java/org/springframework/test/json/JsonContentAssert.java index 70534f7065f..db0212feeb1 100644 --- a/spring-test/src/main/java/org/springframework/test/json/JsonContentAssert.java +++ b/spring-test/src/main/java/org/springframework/test/json/JsonContentAssert.java @@ -16,8 +16,6 @@ package org.springframework.test.json; -import java.nio.charset.Charset; - import org.springframework.http.converter.GenericHttpMessageConverter; import org.springframework.lang.Nullable; @@ -33,19 +31,11 @@ public class JsonContentAssert extends AbstractJsonContentAssertPath can be converted to a value object using the given * {@linkplain GenericHttpMessageConverter json message converter}. - *

Resources to match can be loaded relative to the given - * {@code resourceLoadClass}. If not specified, resources must always be - * absolute. A specific {@link Charset} can be provided if {@code UTF-8} is - * not suitable. * @param json the JSON document to assert * @param jsonMessageConverter the converter to use - * @param resourceLoadClass the class used to load resources - * @param charset the charset of the JSON resources */ - public JsonContentAssert(@Nullable String json, @Nullable GenericHttpMessageConverter jsonMessageConverter, - @Nullable Class resourceLoadClass, @Nullable Charset charset) { - - super(json, jsonMessageConverter, resourceLoadClass, charset, JsonContentAssert.class); + public JsonContentAssert(@Nullable String json, @Nullable GenericHttpMessageConverter jsonMessageConverter) { + super(json, jsonMessageConverter, JsonContentAssert.class); } } diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/assertj/AbstractMockHttpServletResponseAssert.java b/spring-test/src/main/java/org/springframework/test/web/servlet/assertj/AbstractMockHttpServletResponseAssert.java index decb5a21e92..c320bea1012 100644 --- a/spring-test/src/main/java/org/springframework/test/web/servlet/assertj/AbstractMockHttpServletResponseAssert.java +++ b/spring-test/src/main/java/org/springframework/test/web/servlet/assertj/AbstractMockHttpServletResponseAssert.java @@ -18,9 +18,16 @@ package org.springframework.test.web.servlet.assertj; import java.nio.charset.Charset; +import org.assertj.core.api.AbstractByteArrayAssert; +import org.assertj.core.api.AbstractStringAssert; +import org.assertj.core.api.Assertions; +import org.assertj.core.api.ByteArrayAssert; + import org.springframework.http.converter.GenericHttpMessageConverter; import org.springframework.lang.Nullable; import org.springframework.mock.web.MockHttpServletResponse; +import org.springframework.test.json.AbstractJsonContentAssert; +import org.springframework.test.json.JsonContentAssert; import org.springframework.test.web.UriAssert; /** @@ -45,22 +52,62 @@ public abstract class AbstractMockHttpServletResponseAssertExamples:

 	 * // Check that the response body is equal to "Hello World":
-	 * assertThat(response).body().isEqualTo("Hello World");
+	 * assertThat(response).bodyText().isEqualTo("Hello World");
+	 * 
+ */ + public AbstractStringAssert bodyText() { + return Assertions.assertThat(readBody()); + } + + /** + * Return a new {@linkplain AbstractJsonContentAssert assertion} object that + * uses the response body converted to text as the object to test. Compared + * to {@link #bodyText()}, the assertion object provides dedicated JSON + * support. + *

Examples:


+	 * // Check that the response body is strictly equal to the content of
+	 * // "/com/acme/sample/person-created.json":
+	 * assertThat(response).bodyJson()
+	 *         .isStrictlyEqualToJson("/com/acme/sample/person-created.json");
+	 *
+	 * // Check that the response is strictly equal to the content of the
+	 * // specified file located in the same package as the PersonController:
+	 * assertThat(response).bodyJson().withResourceLoadClass(PersonController.class)
+	 *         .isStrictlyEqualToJson("person-created.json");
+	 * 
+ * The returned assert object also supports JSON path expressions. + *

Examples:


+	 * // Check that the JSON document does not have an "error" element
+	 * assertThat(response).bodyJson().doesNotHavePath("$.error");
 	 *
-	 * // Check that the response body is strictly equal to the content of "test.json":
-	 * assertThat(response).body().json().isStrictlyEqualToJson("test.json");
+	 * // Check that the JSON document as a top level "message" element
+	 * assertThat(response).bodyJson()
+	 *         .extractingPath("$.message").asString().isEqualTo("hello");
 	 * 
*/ - public ResponseBodyAssert body() { - return new ResponseBodyAssert(getResponse().getContentAsByteArray(), - Charset.forName(getResponse().getCharacterEncoding()), this.jsonMessageConverter); + public AbstractJsonContentAssert bodyJson() { + return new JsonContentAssert(readBody(), this.jsonMessageConverter); + } + + private String readBody() { + return new String(getResponse().getContentAsByteArray(), + Charset.forName(getResponse().getCharacterEncoding())); + } + + /** + * Return a new {@linkplain AbstractByteArrayAssert assertion} object that + * uses the response body as the object to test. + * @see #bodyText() + * @see #bodyJson() + */ + public AbstractByteArrayAssert body() { + return new ByteArrayAssert(getResponse().getContentAsByteArray()); } /** @@ -89,6 +136,14 @@ public abstract class AbstractMockHttpServletResponseAssert { - - private final Charset characterEncoding; - - @Nullable - private final GenericHttpMessageConverter jsonMessageConverter; - - ResponseBodyAssert(byte[] actual, Charset characterEncoding, - @Nullable GenericHttpMessageConverter jsonMessageConverter) { - - super(actual, ResponseBodyAssert.class); - this.characterEncoding = characterEncoding; - this.jsonMessageConverter = jsonMessageConverter; - as("Response body"); - } - - /** - * Return a new {@linkplain AbstractJsonContentAssert assertion} object that - * provides {@linkplain com.jayway.jsonpath.JsonPath JSON path} assertions on - * the response body. - */ - public AbstractJsonContentAssert jsonPath() { - return new JsonContentAssert(getJson(), this.jsonMessageConverter, null, this.characterEncoding) - .as("JSON body"); - } - - /** - * Return a new {@linkplain AbstractJsonContentAssert 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. - *

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. - *

Example:


-	 * // Check that the response is strictly equal to the content of
-	 * // "/com/acme/web/person/person-created.json":
-	 * assertThat(...).body().json()
-	 *         .isStrictlyEqualToJson("/com/acme/web/person/person-created.json");
-	 * 
- */ - public AbstractJsonContentAssert json() { - return json(null); - } - - /** - * Return a new {@linkplain AbstractJsonContentAssert 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. - *

Locations for JSON documents can be absolute using a leading slash, or - * relative to the given {@code resourceLoadClass}. - *

Example:


-	 * // 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");
-	 * 
- * @param resourceLoadClass the class used to load relative JSON documents - * @see ClassPathResource#ClassPathResource(String, Class) - */ - public AbstractJsonContentAssert json(@Nullable Class resourceLoadClass) { - return new JsonContentAssert(getJson(), this.jsonMessageConverter, resourceLoadClass, this.characterEncoding) - .as("JSON body"); - } - - /** - * Verify that the response body is equal to the given {@link String}. - *

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() - */ - public ResponseBodyAssert isEqualTo(String expected) { - asString().isEqualTo(expected); - return this; - } - - /** - * 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() { - return asString(this.characterEncoding); - } - - private String getJson() { - return new String(this.actual, this.characterEncoding); - } - -} diff --git a/spring-test/src/test/java/org/springframework/test/json/AbstractJsonContentAssertTests.java b/spring-test/src/test/java/org/springframework/test/json/AbstractJsonContentAssertTests.java index 5453aebcda9..14f1ad8dcf2 100644 --- a/spring-test/src/test/java/org/springframework/test/json/AbstractJsonContentAssertTests.java +++ b/spring-test/src/test/java/org/springframework/test/json/AbstractJsonContentAssertTests.java @@ -19,7 +19,6 @@ package org.springframework.test.json; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; -import java.nio.charset.Charset; import java.nio.file.Files; import java.nio.file.Path; import java.util.List; @@ -146,7 +145,6 @@ class AbstractJsonContentAssertTests { assertThat(forJson(NULLS)).doesNotHavePath("$.missing"); } - @Test void doesNotHavePathForPresent() { String expression = "$.valuename"; @@ -154,7 +152,6 @@ class AbstractJsonContentAssertTests { .isThrownBy(() -> assertThat(forJson(NULLS)).doesNotHavePath(expression)) .satisfies(hasFailedToNotMatchPath(expression)); } - } @Nested @@ -330,13 +327,12 @@ class AbstractJsonContentAssertTests { private record Customer(long id, String username) {} private AssertProvider> forJson(@Nullable String json) { - return () -> new TestJsonContentAssert(json, null, null, null); + return () -> new TestJsonContentAssert(json, null); } private AssertProvider> forJson(@Nullable String json, GenericHttpMessageConverter jsonHttpMessageConverter) { - return () -> new TestJsonContentAssert(json, jsonHttpMessageConverter, null, null); + return () -> new TestJsonContentAssert(json, jsonHttpMessageConverter); } - } @Nested @@ -548,7 +544,6 @@ class AbstractJsonContentAssertTests { .isThrownBy(() -> assertThat(forJson(SOURCE)).isStrictlyEqualTo(expected)); } - @Test void isNotEqualToWhenStringIsMatchingShouldFail() { assertThatExceptionOfType(AssertionError.class) @@ -720,10 +715,19 @@ class AbstractJsonContentAssertTests { assertThat(forJson(SOURCE)).isNotStrictlyEqualTo(expected); } - private AssertProvider> forJson(@Nullable String json) { - return () -> new TestJsonContentAssert(json, null, getClass(), null); + @Test + void withResourceLoadClassShouldAllowToLoadRelativeContent() { + AbstractJsonContentAssert jsonAssert = assertThat(forJson(NULLS)).withResourceLoadClass(String.class); + assertThatIllegalStateException() + .isThrownBy(() -> jsonAssert.isLenientlyEqualTo("nulls.json")) + .withMessage("Unable to load JSON from class path resource [java/lang/nulls.json]"); + + assertThat(forJson(NULLS)).withResourceLoadClass(JsonContent.class).isLenientlyEqualTo("nulls.json"); } + private AssertProvider> forJson(@Nullable String json) { + return () -> new TestJsonContentAssert(json, null).withResourceLoadClass(getClass()); + } } @@ -768,13 +772,13 @@ class AbstractJsonContentAssertTests { } private AssertProvider> forJson(@Nullable String json) { - return () -> new TestJsonContentAssert(json, null, null, null); + return () -> new TestJsonContentAssert(json, null); } private static class TestJsonContentAssert extends AbstractJsonContentAssert { - public TestJsonContentAssert(@Nullable String json, @Nullable GenericHttpMessageConverter jsonMessageConverter, @Nullable Class resourceLoadClass, @Nullable Charset charset) { - super(json, jsonMessageConverter, resourceLoadClass, charset, TestJsonContentAssert.class); + public TestJsonContentAssert(@Nullable String json, @Nullable GenericHttpMessageConverter jsonMessageConverter) { + super(json, jsonMessageConverter, TestJsonContentAssert.class); } } diff --git a/spring-test/src/test/java/org/springframework/test/web/servlet/assertj/AbstractMockHttpServletResponseAssertTests.java b/spring-test/src/test/java/org/springframework/test/web/servlet/assertj/AbstractMockHttpServletResponseAssertTests.java index 6c0de703ac1..18f8b711032 100644 --- a/spring-test/src/test/java/org/springframework/test/web/servlet/assertj/AbstractMockHttpServletResponseAssertTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/servlet/assertj/AbstractMockHttpServletResponseAssertTests.java @@ -16,15 +16,17 @@ package org.springframework.test.web.servlet.assertj; - import java.io.UnsupportedEncodingException; import java.nio.charset.StandardCharsets; +import org.assertj.core.api.AssertProvider; import org.junit.jupiter.api.Test; import org.springframework.http.HttpHeaders; import org.springframework.mock.web.MockHttpServletResponse; +import org.springframework.test.json.JsonContent; +import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; /** @@ -34,12 +36,50 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType; */ public class AbstractMockHttpServletResponseAssertTests { + @Test + void bodyText() { + MockHttpServletResponse response = createResponse("OK"); + assertThat(fromResponse(response)).bodyText().isEqualTo("OK"); + } + + @Test + void bodyJsonWithJsonPath() { + MockHttpServletResponse response = createResponse("{\"albumById\": {\"name\": \"Greatest hits\"}}"); + assertThat(fromResponse(response)).bodyJson() + .extractingPath("$.albumById.name").isEqualTo("Greatest hits"); + } + + @Test + void bodyJsonCanLoadResourceRelativeToClass() { + MockHttpServletResponse response = createResponse("{ \"name\" : \"Spring\", \"age\" : 123 }"); + // See org/springframework/test/json/example.json + assertThat(fromResponse(response)).bodyJson().withResourceLoadClass(JsonContent.class) + .isLenientlyEqualTo("example.json"); + } + + @Test + void bodyWithByteArray() throws UnsupportedEncodingException { + byte[] bytes = "OK".getBytes(StandardCharsets.UTF_8); + MockHttpServletResponse response = new MockHttpServletResponse(); + response.getWriter().write("OK"); + response.setContentType(StandardCharsets.UTF_8.name()); + assertThat(fromResponse(response)).body().isEqualTo(bytes); + } + + @Test + void hasBodyTextEqualTo() throws UnsupportedEncodingException { + MockHttpServletResponse response = new MockHttpServletResponse(); + response.getWriter().write("OK"); + response.setContentType(StandardCharsets.UTF_8.name()); + assertThat(fromResponse(response)).hasBodyTextEqualTo("OK"); + } + @Test void hasForwardedUrl() { String forwardedUrl = "https://example.com/42"; MockHttpServletResponse response = new MockHttpServletResponse(); response.setForwardedUrl(forwardedUrl); - assertThat(response).hasForwardedUrl(forwardedUrl); + assertThat(fromResponse(response)).hasForwardedUrl(forwardedUrl); } @Test @@ -48,7 +88,7 @@ public class AbstractMockHttpServletResponseAssertTests { MockHttpServletResponse response = new MockHttpServletResponse(); response.setForwardedUrl(forwardedUrl); assertThatExceptionOfType(AssertionError.class) - .isThrownBy(() -> assertThat(response).hasForwardedUrl("another")) + .isThrownBy(() -> assertThat(fromResponse(response)).hasForwardedUrl("another")) .withMessageContainingAll("Forwarded URL", forwardedUrl, "another"); } @@ -57,7 +97,7 @@ public class AbstractMockHttpServletResponseAssertTests { String redirectedUrl = "https://example.com/42"; MockHttpServletResponse response = new MockHttpServletResponse(); response.addHeader(HttpHeaders.LOCATION, redirectedUrl); - assertThat(response).hasRedirectedUrl(redirectedUrl); + assertThat(fromResponse(response)).hasRedirectedUrl(redirectedUrl); } @Test @@ -66,29 +106,25 @@ public class AbstractMockHttpServletResponseAssertTests { MockHttpServletResponse response = new MockHttpServletResponse(); response.addHeader(HttpHeaders.LOCATION, redirectedUrl); assertThatExceptionOfType(AssertionError.class) - .isThrownBy(() -> assertThat(response).hasRedirectedUrl("another")) + .isThrownBy(() -> assertThat(fromResponse(response)).hasRedirectedUrl("another")) .withMessageContainingAll("Redirected URL", redirectedUrl, "another"); } - @Test - void bodyHasContent() throws UnsupportedEncodingException { - MockHttpServletResponse response = new MockHttpServletResponse(); - response.getWriter().write("OK"); - assertThat(response).body().asString().isEqualTo("OK"); - } - @Test - void bodyHasContentWithResponseCharacterEncoding() throws UnsupportedEncodingException { - byte[] bytes = "OK".getBytes(StandardCharsets.UTF_8); - MockHttpServletResponse response = new MockHttpServletResponse(); - response.getWriter().write("OK"); - response.setContentType(StandardCharsets.UTF_8.name()); - assertThat(response).body().isEqualTo(bytes); + private MockHttpServletResponse createResponse(String body) { + try { + MockHttpServletResponse response = new MockHttpServletResponse(); + response.setContentType(StandardCharsets.UTF_8.name()); + response.getWriter().write(body); + return response; + } + catch (UnsupportedEncodingException ex) { + throw new IllegalStateException(ex); + } } - - private static ResponseAssert assertThat(MockHttpServletResponse response) { - return new ResponseAssert(response); + private static AssertProvider fromResponse(MockHttpServletResponse response) { + return () -> new ResponseAssert(response); } diff --git a/spring-test/src/test/java/org/springframework/test/web/servlet/assertj/AssertableMockMvcIntegrationTests.java b/spring-test/src/test/java/org/springframework/test/web/servlet/assertj/AssertableMockMvcIntegrationTests.java index 8e6f3eb7359..34a164f8878 100644 --- a/spring-test/src/test/java/org/springframework/test/web/servlet/assertj/AssertableMockMvcIntegrationTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/servlet/assertj/AssertableMockMvcIntegrationTests.java @@ -250,19 +250,19 @@ public class AssertableMockMvcIntegrationTests { @Test void jsonPathContent() { - assertThat(perform(get("/message"))).body().jsonPath() + assertThat(perform(get("/message"))).bodyJson() .extractingPath("$.message").asString().isEqualTo("hello"); } @Test void jsonContentCanLoadResourceFromClasspath() { - assertThat(perform(get("/message"))).body().json().isLenientlyEqualTo( + assertThat(perform(get("/message"))).bodyJson().isLenientlyEqualTo( new ClassPathResource("message.json", AssertableMockMvcIntegrationTests.class)); } @Test void jsonContentUsingResourceLoaderClass() { - assertThat(perform(get("/message"))).body().json(AssertableMockMvcIntegrationTests.class) + assertThat(perform(get("/message"))).bodyJson().withResourceLoadClass(AssertableMockMvcIntegrationTests.class) .isLenientlyEqualTo("message.json"); } diff --git a/spring-test/src/test/java/org/springframework/test/web/servlet/assertj/AssertableMockMvcTests.java b/spring-test/src/test/java/org/springframework/test/web/servlet/assertj/AssertableMockMvcTests.java index 4baa08b154e..587f0f521ca 100644 --- a/spring-test/src/test/java/org/springframework/test/web/servlet/assertj/AssertableMockMvcTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/servlet/assertj/AssertableMockMvcTests.java @@ -67,26 +67,26 @@ class AssertableMockMvcTests { void createWithExistingWebApplicationContext() { try (GenericWebApplicationContext wac = create(WebConfiguration.class)) { AssertableMockMvc mockMvc = AssertableMockMvc.from(wac); - assertThat(mockMvc.perform(post("/increase"))).body().isEqualTo("counter 41"); - assertThat(mockMvc.perform(post("/increase"))).body().isEqualTo("counter 42"); + assertThat(mockMvc.perform(post("/increase"))).hasBodyTextEqualTo("counter 41"); + assertThat(mockMvc.perform(post("/increase"))).hasBodyTextEqualTo("counter 42"); } } @Test void createWithControllerClassShouldInstantiateControllers() { AssertableMockMvc mockMvc = AssertableMockMvc.of(HelloController.class, CounterController.class); - assertThat(mockMvc.perform(get("/hello"))).body().isEqualTo("Hello World"); - assertThat(mockMvc.perform(post("/increase"))).body().isEqualTo("counter 1"); - assertThat(mockMvc.perform(post("/increase"))).body().isEqualTo("counter 2"); + assertThat(mockMvc.perform(get("/hello"))).hasBodyTextEqualTo("Hello World"); + assertThat(mockMvc.perform(post("/increase"))).hasBodyTextEqualTo("counter 1"); + assertThat(mockMvc.perform(post("/increase"))).hasBodyTextEqualTo("counter 2"); } @Test void createWithControllersShouldUseThemAsIs() { AssertableMockMvc mockMvc = AssertableMockMvc.of(new HelloController(), new CounterController(new AtomicInteger(41))); - assertThat(mockMvc.perform(get("/hello"))).body().isEqualTo("Hello World"); - assertThat(mockMvc.perform(post("/increase"))).body().isEqualTo("counter 42"); - assertThat(mockMvc.perform(post("/increase"))).body().isEqualTo("counter 43"); + assertThat(mockMvc.perform(get("/hello"))).hasBodyTextEqualTo("Hello World"); + assertThat(mockMvc.perform(post("/increase"))).hasBodyTextEqualTo("counter 42"); + assertThat(mockMvc.perform(post("/increase"))).hasBodyTextEqualTo("counter 43"); } @Test @@ -99,7 +99,7 @@ class AssertableMockMvcTests { @Test void createWithControllersHasNoHttpMessageConverter() { AssertableMockMvc mockMvc = AssertableMockMvc.of(new HelloController()); - AbstractJsonContentAssert jsonContentAssert = assertThat(mockMvc.perform(get("/json"))).hasStatusOk().body().jsonPath(); + AbstractJsonContentAssert jsonContentAssert = assertThat(mockMvc.perform(get("/json"))).hasStatusOk().bodyJson(); assertThatIllegalStateException() .isThrownBy(() -> jsonContentAssert.extractingPath("$").convertTo(Message.class)) .withMessageContaining("No JSON message converter available"); @@ -109,7 +109,7 @@ class AssertableMockMvcTests { void createWithControllerCanConfigureHttpMessageConverters() { AssertableMockMvc mockMvc = AssertableMockMvc.of(HelloController.class) .withHttpMessageConverters(List.of(jsonHttpMessageConverter)); - assertThat(mockMvc.perform(get("/json"))).hasStatusOk().body().jsonPath() + assertThat(mockMvc.perform(get("/json"))).hasStatusOk().bodyJson() .extractingPath("$").convertTo(Message.class).satisfies(message -> { assertThat(message.message()).isEqualTo("Hello World"); assertThat(message.counter()).isEqualTo(42); @@ -122,7 +122,7 @@ class AssertableMockMvcTests { MappingJackson2HttpMessageConverter converter = spy(jsonHttpMessageConverter); AssertableMockMvc mockMvc = AssertableMockMvc.of(HelloController.class) .withHttpMessageConverters(List.of(mock(), mock(), converter)); - assertThat(mockMvc.perform(get("/json"))).hasStatusOk().body().jsonPath() + assertThat(mockMvc.perform(get("/json"))).hasStatusOk().bodyJson() .extractingPath("$").convertTo(Message.class).satisfies(message -> { assertThat(message.message()).isEqualTo("Hello World"); assertThat(message.counter()).isEqualTo(42); diff --git a/spring-test/src/test/java/org/springframework/test/web/servlet/assertj/ResponseBodyAssertTests.java b/spring-test/src/test/java/org/springframework/test/web/servlet/assertj/ResponseBodyAssertTests.java deleted file mode 100644 index 0284636c3d0..00000000000 --- a/spring-test/src/test/java/org/springframework/test/web/servlet/assertj/ResponseBodyAssertTests.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright 2002-2024 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.test.web.servlet.assertj; - - -import java.io.UnsupportedEncodingException; -import java.nio.charset.Charset; -import java.nio.charset.StandardCharsets; - -import org.assertj.core.api.AssertProvider; -import org.junit.jupiter.api.Test; - -import org.springframework.mock.web.MockHttpServletResponse; -import org.springframework.test.json.JsonContent; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link ResponseBodyAssert}. - * - * @author Brian Clozel - * @author Stephane Nicoll - */ -class ResponseBodyAssertTests { - - @Test - void isEqualToWithByteArray() { - MockHttpServletResponse response = createResponse("hello"); - response.setCharacterEncoding(StandardCharsets.UTF_8.name()); - assertThat(fromResponse(response)).isEqualTo("hello".getBytes(StandardCharsets.UTF_8)); - } - - @Test - void isEqualToWithString() { - MockHttpServletResponse response = createResponse("hello"); - assertThat(fromResponse(response)).isEqualTo("hello"); - } - - @Test - void jsonPathWithJsonResponseShouldPass() { - MockHttpServletResponse response = createResponse("{\"message\": \"hello\"}"); - assertThat(fromResponse(response)).jsonPath().extractingPath("$.message").isEqualTo("hello"); - } - - @Test - void jsonPathWithJsonCompatibleResponseShouldPass() { - MockHttpServletResponse response = createResponse("{\"albumById\": {\"name\": \"Greatest hits\"}}"); - assertThat(fromResponse(response)).jsonPath() - .extractingPath("$.albumById.name").isEqualTo("Greatest hits"); - } - - @Test - void jsonCanLoadResourceRelativeToClass() { - MockHttpServletResponse response = createResponse("{ \"name\" : \"Spring\", \"age\" : 123 }"); - // See org/springframework/test/json/example.json - assertThat(fromResponse(response)).json(JsonContent.class).isLenientlyEqualTo("example.json"); - } - - private MockHttpServletResponse createResponse(String body) { - try { - MockHttpServletResponse response = new MockHttpServletResponse(); - response.getWriter().print(body); - return response; - } - catch (UnsupportedEncodingException ex) { - throw new IllegalStateException(ex); - } - } - - private AssertProvider fromResponse(MockHttpServletResponse response) { - return () -> new ResponseBodyAssert(response.getContentAsByteArray(), Charset.forName(response.getCharacterEncoding()), null); - } - -}