Browse Source

Add shortcuts for frequently used assertions

See gh-32712
pull/32782/head
Stéphane Nicoll 2 years ago
parent
commit
bcecce7aac
  1. 105
      spring-test/src/main/java/org/springframework/test/web/servlet/assertj/AbstractHttpServletResponseAssert.java
  2. 10
      spring-test/src/main/java/org/springframework/test/web/servlet/assertj/MvcTestResultAssert.java
  3. 59
      spring-test/src/test/java/org/springframework/test/web/servlet/assertj/AbstractHttpServletResponseAssertTests.java
  4. 14
      spring-test/src/test/java/org/springframework/test/web/servlet/assertj/MockMvcTesterIntegrationTests.java

105
spring-test/src/main/java/org/springframework/test/web/servlet/assertj/AbstractHttpServletResponseAssert.java

@ -28,7 +28,9 @@ import org.assertj.core.api.Assertions; @@ -28,7 +28,9 @@ import org.assertj.core.api.Assertions;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.HttpStatus.Series;
import org.springframework.http.MediaType;
import org.springframework.test.http.HttpHeadersAssert;
import org.springframework.test.http.MediaTypeAssert;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.util.function.SingletonSupplier;
@ -48,15 +50,24 @@ import org.springframework.util.function.SingletonSupplier; @@ -48,15 +50,24 @@ import org.springframework.util.function.SingletonSupplier;
public abstract class AbstractHttpServletResponseAssert<R extends HttpServletResponse, SELF extends AbstractHttpServletResponseAssert<R, SELF, ACTUAL>, ACTUAL>
extends AbstractObjectAssert<SELF, ACTUAL> {
private final Supplier<AbstractIntegerAssert<?>> statusAssert;
private final Supplier<MediaTypeAssert> contentTypeAssertSupplier;
private final Supplier<HttpHeadersAssert> headersAssertSupplier;
private final Supplier<AbstractIntegerAssert<?>> statusAssert;
protected AbstractHttpServletResponseAssert(ACTUAL actual, Class<?> selfType) {
super(actual, selfType);
this.statusAssert = SingletonSupplier.of(() -> Assertions.assertThat(getResponse().getStatus()).as("HTTP status code"));
this.contentTypeAssertSupplier = SingletonSupplier.of(() -> new MediaTypeAssert(getResponse().getContentType()));
this.headersAssertSupplier = SingletonSupplier.of(() -> new HttpHeadersAssert(getHttpHeaders(getResponse())));
this.statusAssert = SingletonSupplier.of(() -> Assertions.assertThat(getResponse().getStatus()).as("HTTP status code"));
}
private static HttpHeaders getHttpHeaders(HttpServletResponse response) {
MultiValueMap<String, String> headers = new LinkedMultiValueMap<>();
response.getHeaderNames().forEach(name -> headers.put(name, new ArrayList<>(response.getHeaders(name))));
return new HttpHeaders(headers);
}
/**
@ -67,6 +78,14 @@ public abstract class AbstractHttpServletResponseAssert<R extends HttpServletRes @@ -67,6 +78,14 @@ public abstract class AbstractHttpServletResponseAssert<R extends HttpServletRes
*/
protected abstract R getResponse();
/**
* Return a new {@linkplain MediaTypeAssert assertion} object that uses the
* response's {@linkplain MediaType content type} as the object to test.
*/
public MediaTypeAssert contentType() {
return this.contentTypeAssertSupplier.get();
}
/**
* Return a new {@linkplain HttpHeadersAssert assertion} object that uses
* {@link HttpHeaders} as the object to test. The returned assertion
@ -84,6 +103,82 @@ public abstract class AbstractHttpServletResponseAssert<R extends HttpServletRes @@ -84,6 +103,82 @@ public abstract class AbstractHttpServletResponseAssert<R extends HttpServletRes
return this.headersAssertSupplier.get();
}
// Content-type shortcuts
/**
* Verify that the response's {@code Content-Type} is equal to the given value.
* @param contentType the expected content type
*/
public SELF hasContentType(MediaType contentType) {
contentType().isEqualTo(contentType);
return this.myself;
}
/**
* Verify that the response's {@code Content-Type} is equal to the given
* string representation.
* @param contentType the expected content type
*/
public SELF hasContentType(String contentType) {
contentType().isEqualTo(contentType);
return this.myself;
}
/**
* Verify that the response's {@code Content-Type} is
* {@linkplain MediaType#isCompatibleWith(MediaType) compatible} with the
* given value.
* @param contentType the expected compatible content type
*/
public SELF hasContentTypeCompatibleWith(MediaType contentType) {
contentType().isCompatibleWith(contentType);
return this.myself;
}
/**
* Verify that the response's {@code Content-Type} is
* {@linkplain MediaType#isCompatibleWith(MediaType) compatible} with the
* given string representation.
* @param contentType the expected compatible content type
*/
public SELF hasContentTypeCompatibleWith(String contentType) {
contentType().isCompatibleWith(contentType);
return this.myself;
}
// Headers shortcuts
/**
* Verify that the response contains a header with the given {@code name}.
* @param name the name of an expected HTTP header
*/
public SELF containsHeader(String name) {
headers().containsHeader(name);
return this.myself;
}
/**
* Verify that the response does not contain a header with the given {@code name}.
* @param name the name of an HTTP header that should not be present
*/
public SELF doesNotContainHeader(String name) {
headers().doesNotContainHeader(name);
return this.myself;
}
/**
* Verify that the response contains a header with the given {@code name}
* and primary {@code value}.
* @param name the name of an expected HTTP header
* @param value the expected value of the header
*/
public SELF hasHeader(String name, String value) {
headers().hasValue(name, value);
return this.myself;
}
// Status
/**
* Verify that the HTTP status is equal to the specified status code.
* @param status the expected HTTP status code
@ -159,10 +254,4 @@ public abstract class AbstractHttpServletResponseAssert<R extends HttpServletRes @@ -159,10 +254,4 @@ public abstract class AbstractHttpServletResponseAssert<R extends HttpServletRes
return this.statusAssert.get();
}
private static HttpHeaders getHttpHeaders(HttpServletResponse response) {
MultiValueMap<String, String> headers = new LinkedMultiValueMap<>();
response.getHeaderNames().forEach(name -> headers.put(name, new ArrayList<>(response.getHeaders(name))));
return new HttpHeaders(headers);
}
}

10
spring-test/src/main/java/org/springframework/test/web/servlet/assertj/MvcTestResultAssert.java

@ -30,12 +30,10 @@ import org.assertj.core.api.ObjectAssert; @@ -30,12 +30,10 @@ import org.assertj.core.api.ObjectAssert;
import org.assertj.core.error.BasicErrorMessageFactory;
import org.assertj.core.internal.Failures;
import org.springframework.http.MediaType;
import org.springframework.http.converter.GenericHttpMessageConverter;
import org.springframework.lang.Nullable;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.test.http.MediaTypeAssert;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.ResultHandler;
import org.springframework.test.web.servlet.ResultMatcher;
@ -87,14 +85,6 @@ public class MvcTestResultAssert extends AbstractMockHttpServletResponseAssert<M @@ -87,14 +85,6 @@ public class MvcTestResultAssert extends AbstractMockHttpServletResponseAssert<M
return new CookieMapAssert(getMvcResult().getResponse().getCookies());
}
/**
* Return a new {@linkplain MediaTypeAssert assertion} object that uses the
* response's {@linkplain MediaType content type} as the object to test.
*/
public MediaTypeAssert contentType() {
return new MediaTypeAssert(getMvcResult().getResponse().getContentType());
}
/**
* Return a new {@linkplain HandlerResultAssert assertion} object that uses
* the handler as the object to test. For a method invocation on a

59
spring-test/src/test/java/org/springframework/test/web/servlet/assertj/AbstractHttpServletResponseAssertTests.java

@ -23,6 +23,7 @@ import org.junit.jupiter.api.Nested; @@ -23,6 +23,7 @@ import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.mock.web.MockHttpServletResponse;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
@ -37,13 +38,30 @@ class AbstractHttpServletResponseAssertTests { @@ -37,13 +38,30 @@ class AbstractHttpServletResponseAssertTests {
@Nested
class HeadersTests {
@Test
void containsHeader() {
MockHttpServletResponse response = createResponse(Map.of("n1", "v1", "n2", "v2", "n3", "v3"));
assertThat(response).containsHeader("n1");
}
@Test
void doesNotContainHeader() {
MockHttpServletResponse response = createResponse(Map.of("n1", "v1", "n2", "v2", "n3", "v3"));
assertThat(response).doesNotContainHeader("n4");
}
@Test
void hasHeader() {
MockHttpServletResponse response = createResponse(Map.of("n1", "v1", "n2", "v2", "n3", "v3"));
assertThat(response).hasHeader("n1", "v1");
}
@Test
void headersAreMatching() {
MockHttpServletResponse response = createResponse(Map.of("n1", "v1", "n2", "v2", "n3", "v3"));
assertThat(response).headers().containsHeaders("n1", "n2", "n3");
}
private MockHttpServletResponse createResponse(Map<String, String> headers) {
MockHttpServletResponse response = new MockHttpServletResponse();
headers.forEach(response::addHeader);
@ -51,6 +69,45 @@ class AbstractHttpServletResponseAssertTests { @@ -51,6 +69,45 @@ class AbstractHttpServletResponseAssertTests {
}
}
@Nested
class ContentTypeTests {
@Test
void contentType() {
MockHttpServletResponse response = createResponse("text/plain");
assertThat(response).hasContentType(MediaType.TEXT_PLAIN);
}
@Test
void contentTypeAndRepresentation() {
MockHttpServletResponse response = createResponse("text/plain");
assertThat(response).hasContentType("text/plain");
}
@Test
void contentTypeCompatibleWith() {
MockHttpServletResponse response = createResponse("application/json;charset=UTF-8");
assertThat(response).hasContentTypeCompatibleWith(MediaType.APPLICATION_JSON);
}
@Test
void contentTypeCompatibleWithAndStringRepresentation() {
MockHttpServletResponse response = createResponse("text/plain");
assertThat(response).hasContentTypeCompatibleWith("text/*");
}
@Test
void contentTypeCanBeAsserted() {
MockHttpServletResponse response = createResponse("text/plain");
assertThat(response).contentType().isInstanceOf(MediaType.class).isCompatibleWith("text/*").isNotNull();
}
private MockHttpServletResponse createResponse(String contentType) {
MockHttpServletResponse response = new MockHttpServletResponse();
response.setContentType(contentType);
return response;
}
}
@Nested
class StatusTests {

14
spring-test/src/test/java/org/springframework/test/web/servlet/assertj/MockMvcTesterIntegrationTests.java

@ -138,16 +138,6 @@ public class MockMvcTesterIntegrationTests { @@ -138,16 +138,6 @@ public class MockMvcTesterIntegrationTests {
}
}
@Nested
class ContentTypeTests {
@Test
void contentType() {
assertThat(perform(get("/greet"))).contentType().isCompatibleWith("text/plain");
}
}
@Nested
class StatusTests {
@ -168,8 +158,8 @@ public class MockMvcTesterIntegrationTests { @@ -168,8 +158,8 @@ public class MockMvcTesterIntegrationTests {
@Test
void shouldAssertHeader() {
assertThat(perform(get("/greet"))).headers()
.hasValue("Content-Type", "text/plain;charset=ISO-8859-1");
assertThat(perform(get("/greet")))
.hasHeader("Content-Type", "text/plain;charset=ISO-8859-1");
}
@Test

Loading…
Cancel
Save