Browse Source
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-32712pull/32782/head
10 changed files with 193 additions and 299 deletions
@ -1,130 +0,0 @@
@@ -1,130 +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.nio.charset.Charset; |
||||
|
||||
import jakarta.servlet.http.HttpServletResponse; |
||||
import org.assertj.core.api.AbstractByteArrayAssert; |
||||
import org.assertj.core.api.AbstractStringAssert; |
||||
|
||||
import org.springframework.core.io.ClassPathResource; |
||||
import org.springframework.http.converter.GenericHttpMessageConverter; |
||||
import org.springframework.lang.Nullable; |
||||
import org.springframework.test.json.AbstractJsonContentAssert; |
||||
import org.springframework.test.json.JsonContentAssert; |
||||
|
||||
/** |
||||
* AssertJ {@link org.assertj.core.api.Assert assertions} that can be applied to |
||||
* the response body. |
||||
* |
||||
* @author Stephane Nicoll |
||||
* @author Brian Clozel |
||||
* @since 6.2 |
||||
*/ |
||||
public class ResponseBodyAssert extends AbstractByteArrayAssert<ResponseBodyAssert> { |
||||
|
||||
private final Charset characterEncoding; |
||||
|
||||
@Nullable |
||||
private final GenericHttpMessageConverter<Object> jsonMessageConverter; |
||||
|
||||
ResponseBodyAssert(byte[] actual, Charset characterEncoding, |
||||
@Nullable GenericHttpMessageConverter<Object> 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. |
||||
* <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() |
||||
* .isStrictlyEqualToJson("/com/acme/web/person/person-created.json"); |
||||
* </code></pre> |
||||
*/ |
||||
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. |
||||
* <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 |
||||
* @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}. |
||||
* <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() |
||||
*/ |
||||
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); |
||||
} |
||||
|
||||
} |
||||
@ -1,88 +0,0 @@
@@ -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<ResponseBodyAssert> fromResponse(MockHttpServletResponse response) { |
||||
return () -> new ResponseBodyAssert(response.getContentAsByteArray(), Charset.forName(response.getCharacterEncoding()), null); |
||||
} |
||||
|
||||
} |
||||
Loading…
Reference in new issue