diff --git a/spring-test/src/main/java/org/springframework/test/web/reactive/server/ExchangeActions.java b/spring-test/src/main/java/org/springframework/test/web/reactive/server/ExchangeActions.java index 6c0da4bc552..84e79b0ce24 100644 --- a/spring-test/src/main/java/org/springframework/test/web/reactive/server/ExchangeActions.java +++ b/spring-test/src/main/java/org/springframework/test/web/reactive/server/ExchangeActions.java @@ -15,15 +15,11 @@ */ package org.springframework.test.web.reactive.server; -import java.time.Duration; import java.util.Collections; import java.util.List; -import java.util.function.Consumer; import org.springframework.core.ResolvableType; import org.springframework.http.HttpHeaders; -import org.springframework.test.util.AssertionErrors; -import org.springframework.web.reactive.function.client.ClientResponse; /** * Entry point for applying assertions and actions on a performed exchange. @@ -70,28 +66,21 @@ public final class ExchangeActions { } /** - * Assert the response does not have any content. + * Assertions on the body of the response decoded as one or more response + * entities of the given type. + * @return options for asserting response entities + */ + public ResponseEntityAssertions assertEntity(Class entityType) { + return new ResponseEntityAssertions(this, ResolvableType.forClass(entityType)); + } + + /** + * Assertions on the body of the response. */ public ResponseBodyAssertions assertBody() { return new ResponseBodyAssertions(this); } - /** - * Assert the content of the response. - * @return further options for asserting response entities - */ - public ResponseEntityAssertions assertEntity(Class entityType) { - return assertEntity(ResolvableType.forClass(entityType)); - } - - /** - * Assert the content of the response. - * @return further options for asserting response entities - */ - public ResponseEntityAssertions assertEntity(ResolvableType entityType) { - return new ResponseEntityAssertions(this, entityType); - } - /** * Log debug information about the exchange. */ @@ -99,27 +88,6 @@ public final class ExchangeActions { return new LoggingExchangeConsumer(this); } - /** - * Apply custom assertions on the performed exchange with the help of - * {@link AssertionErrors} or an assertion library such as AssertJ. - *

Consider using statically imported methods to improve readability - * @param consumer consumer that will apply assertions. - */ - public ExchangeActions andAssert(Consumer consumer) { - consumer.accept(this.exchangeInfo); - return this; - } - - /** - * Apply custom actions on the performed exchange. - *

Consider using statically imported methods to improve readability - * @param consumer consumer that will apply the custom action - */ - public ExchangeActions andDo(Consumer consumer) { - consumer.accept(this.exchangeInfo); - return this; - } - /** * Return {@link ExchangeInfo} for direct access to request and response. */ diff --git a/spring-test/src/main/java/org/springframework/test/web/reactive/server/ObjectAssertions.java b/spring-test/src/main/java/org/springframework/test/web/reactive/server/ObjectAssertions.java index ee301af0501..733e775c7d3 100644 --- a/spring-test/src/main/java/org/springframework/test/web/reactive/server/ObjectAssertions.java +++ b/spring-test/src/main/java/org/springframework/test/web/reactive/server/ObjectAssertions.java @@ -19,7 +19,6 @@ import java.time.Duration; import java.util.function.Consumer; import java.util.function.Supplier; -import org.springframework.test.util.AssertionErrors; import org.springframework.web.reactive.function.client.ClientResponse; import static org.springframework.test.util.AssertionErrors.assertEquals; @@ -72,28 +71,16 @@ public class ObjectAssertions> { } /** - * Apply custom assertions on the Object value with the help of - * {@link AssertionErrors} or an assertion library such as AssertJ. - *

Consider using statically imported methods for creating the assertion - * consumer to improve readability of tests. - * @param assertionConsumer consumer that will apply assertions. - */ - public T andAssert(Consumer assertionConsumer) { - assertionConsumer.accept(getValue()); - return self(); - } - - /** - * Apply custom actions on the Object value. - *

Consider using statically imported methods for creating the assertion - * consumer to improve readability of tests. + * Custom assertions on the Object value with a {@link Consumer}. + *

Consider using statically imported methods to improve readability * @param consumer consumer that will apply the custom action */ - public T andDo(Consumer consumer) { - consumer.accept(getValue()); - return self(); + public ExchangeActions consume(Consumer consumer) { + consumer.accept(this.getValue()); + return this.exchangeActions; } + /** * Continue with more assertions or actions on the response. */ diff --git a/spring-test/src/main/java/org/springframework/test/web/reactive/server/ResponseBodyAssertions.java b/spring-test/src/main/java/org/springframework/test/web/reactive/server/ResponseBodyAssertions.java index 6b51c7ef9b0..cf01c162e4d 100644 --- a/spring-test/src/main/java/org/springframework/test/web/reactive/server/ResponseBodyAssertions.java +++ b/spring-test/src/main/java/org/springframework/test/web/reactive/server/ResponseBodyAssertions.java @@ -29,6 +29,7 @@ import org.springframework.web.reactive.function.client.ClientResponse; import static org.springframework.web.reactive.function.BodyExtractors.toMono; /** + * Assertions on the body of the response. * * @author Rossen Stoyanchev * @since 5.0 @@ -53,12 +54,12 @@ public class ResponseBodyAssertions { } /** - * Assert the response decoded as a Map of the given key and value types. + * Assert the response decoded as a Map of String key-value pairs. */ - public MapAssertions asMap(Class keyType, Class valueType) { - ResolvableType type = ResolvableType.forClassWithGenerics(Map.class, keyType, valueType); - Mono> mono = getResponse().body(toMono(type)); - Map map = mono.block(getTimeout()); + public MapAssertions asMap() { + ResolvableType type = ResolvableType.forClassWithGenerics(Map.class, String.class, String.class); + Mono> mono = getResponse().body(toMono(type)); + Map map = mono.block(getTimeout()); return new MapAssertions<>(this.exchangeActions, map, "Response body map"); } diff --git a/spring-test/src/main/java/org/springframework/test/web/reactive/server/ResponseEntityAssertions.java b/spring-test/src/main/java/org/springframework/test/web/reactive/server/ResponseEntityAssertions.java index 78363daa9ea..dd38377f238 100644 --- a/spring-test/src/main/java/org/springframework/test/web/reactive/server/ResponseEntityAssertions.java +++ b/spring-test/src/main/java/org/springframework/test/web/reactive/server/ResponseEntityAssertions.java @@ -16,6 +16,7 @@ package org.springframework.test.web.reactive.server; import java.util.List; +import java.util.Map; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; @@ -32,7 +33,7 @@ import static org.springframework.web.reactive.function.BodyExtractors.toMono; * @param the response entity type * * @author Rossen Stoyanchev - * @sine 5.0 + * @since 5.0 */ public class ResponseEntityAssertions extends ObjectAssertions> { @@ -60,6 +61,17 @@ public class ResponseEntityAssertions extends ObjectAssertions(getExchangeActions(), list, "Response entity collection"); } + /** + * Assert the response decoded as a Map of entities with String keys. + */ + public MapAssertions map() { + ResolvableType keyType = ResolvableType.forClass(String.class); + ResolvableType type = ResolvableType.forClassWithGenerics(Map.class, keyType, this.entityType); + Mono> mono = getResponse().body(toMono(type)); + Map map = mono.block(getTimeout()); + return new MapAssertions<>(getExchangeActions(), map, "Response entity map"); + } + /** * Assert the response content using a {@link StepVerifier}. */ diff --git a/spring-test/src/main/java/org/springframework/test/web/reactive/server/ResponseHeadersAssertions.java b/spring-test/src/main/java/org/springframework/test/web/reactive/server/ResponseHeadersAssertions.java index 245d86fba1b..94b761163cc 100644 --- a/spring-test/src/main/java/org/springframework/test/web/reactive/server/ResponseHeadersAssertions.java +++ b/spring-test/src/main/java/org/springframework/test/web/reactive/server/ResponseHeadersAssertions.java @@ -15,8 +15,7 @@ */ package org.springframework.test.web.reactive.server; -import java.util.Collections; -import java.util.List; +import java.util.function.Consumer; import org.springframework.http.CacheControl; import org.springframework.http.ContentDisposition; @@ -80,4 +79,14 @@ public class ResponseHeadersAssertions { return this.exchangeActions; } + /** + * Custom assertions on the response headers with a {@link Consumer}. + *

Consider using statically imported methods to improve readability + * @param consumer consumer that will apply the custom action + */ + public ExchangeActions consume(Consumer consumer) { + consumer.accept(this.headers); + return this.exchangeActions; + } + } diff --git a/spring-test/src/main/java/org/springframework/test/web/reactive/server/ResponseStatusAssertions.java b/spring-test/src/main/java/org/springframework/test/web/reactive/server/ResponseStatusAssertions.java index 046476c1afd..34772f86e5d 100644 --- a/spring-test/src/main/java/org/springframework/test/web/reactive/server/ResponseStatusAssertions.java +++ b/spring-test/src/main/java/org/springframework/test/web/reactive/server/ResponseStatusAssertions.java @@ -15,6 +15,8 @@ */ package org.springframework.test.web.reactive.server; +import java.util.function.Consumer; + import org.springframework.http.HttpStatus; import static org.springframework.test.util.AssertionErrors.assertEquals; @@ -89,6 +91,16 @@ public class ResponseStatusAssertions { return this.exchangeActions; } + /** + * Custom assertions on the response status with a {@link Consumer}. + *

Consider using statically imported methods to improve readability + * @param consumer consumer that will apply the custom action + */ + public ExchangeActions consume(Consumer consumer) { + consumer.accept(this.httpStatus); + return this.exchangeActions; + } + /** * Assert the response error message. */ @@ -101,119 +113,119 @@ public class ResponseStatusAssertions { * Assert the response status code is {@code HttpStatus.CONTINUE} (100). */ public ExchangeActions isContinue() { - return doMatch(HttpStatus.CONTINUE); + return assertStatusIsEqualTo(HttpStatus.CONTINUE); } /** * Assert the response status code is {@code HttpStatus.SWITCHING_PROTOCOLS} (101). */ public ExchangeActions isSwitchingProtocols() { - return doMatch(HttpStatus.SWITCHING_PROTOCOLS); + return assertStatusIsEqualTo(HttpStatus.SWITCHING_PROTOCOLS); } /** * Assert the response status code is {@code HttpStatus.PROCESSING} (102). */ public ExchangeActions isProcessing() { - return doMatch(HttpStatus.PROCESSING); + return assertStatusIsEqualTo(HttpStatus.PROCESSING); } /** * Assert the response status code is {@code HttpStatus.CHECKPOINT} (103). */ public ExchangeActions isCheckpoint() { - return doMatch(HttpStatus.valueOf(103)); + return assertStatusIsEqualTo(HttpStatus.valueOf(103)); } /** * Assert the response status code is {@code HttpStatus.OK} (200). */ public ExchangeActions isOk() { - return doMatch(HttpStatus.OK); + return assertStatusIsEqualTo(HttpStatus.OK); } /** * Assert the response status code is {@code HttpStatus.CREATED} (201). */ public ExchangeActions isCreated() { - return doMatch(HttpStatus.CREATED); + return assertStatusIsEqualTo(HttpStatus.CREATED); } /** * Assert the response status code is {@code HttpStatus.ACCEPTED} (202). */ public ExchangeActions isAccepted() { - return doMatch(HttpStatus.ACCEPTED); + return assertStatusIsEqualTo(HttpStatus.ACCEPTED); } /** * Assert the response status code is {@code HttpStatus.NON_AUTHORITATIVE_INFORMATION} (203). */ public ExchangeActions isNonAuthoritativeInformation() { - return doMatch(HttpStatus.NON_AUTHORITATIVE_INFORMATION); + return assertStatusIsEqualTo(HttpStatus.NON_AUTHORITATIVE_INFORMATION); } /** * Assert the response status code is {@code HttpStatus.NO_CONTENT} (204). */ public ExchangeActions isNoContent() { - return doMatch(HttpStatus.NO_CONTENT); + return assertStatusIsEqualTo(HttpStatus.NO_CONTENT); } /** * Assert the response status code is {@code HttpStatus.RESET_CONTENT} (205). */ public ExchangeActions isResetContent() { - return doMatch(HttpStatus.RESET_CONTENT); + return assertStatusIsEqualTo(HttpStatus.RESET_CONTENT); } /** * Assert the response status code is {@code HttpStatus.PARTIAL_CONTENT} (206). */ public ExchangeActions isPartialContent() { - return doMatch(HttpStatus.PARTIAL_CONTENT); + return assertStatusIsEqualTo(HttpStatus.PARTIAL_CONTENT); } /** * Assert the response status code is {@code HttpStatus.MULTI_STATUS} (207). */ public ExchangeActions isMultiStatus() { - return doMatch(HttpStatus.MULTI_STATUS); + return assertStatusIsEqualTo(HttpStatus.MULTI_STATUS); } /** * Assert the response status code is {@code HttpStatus.ALREADY_REPORTED} (208). */ public ExchangeActions isAlreadyReported() { - return doMatch(HttpStatus.ALREADY_REPORTED); + return assertStatusIsEqualTo(HttpStatus.ALREADY_REPORTED); } /** * Assert the response status code is {@code HttpStatus.IM_USED} (226). */ public ExchangeActions isImUsed() { - return doMatch(HttpStatus.IM_USED); + return assertStatusIsEqualTo(HttpStatus.IM_USED); } /** * Assert the response status code is {@code HttpStatus.MULTIPLE_CHOICES} (300). */ public ExchangeActions isMultipleChoices() { - return doMatch(HttpStatus.MULTIPLE_CHOICES); + return assertStatusIsEqualTo(HttpStatus.MULTIPLE_CHOICES); } /** * Assert the response status code is {@code HttpStatus.MOVED_PERMANENTLY} (301). */ public ExchangeActions isMovedPermanently() { - return doMatch(HttpStatus.MOVED_PERMANENTLY); + return assertStatusIsEqualTo(HttpStatus.MOVED_PERMANENTLY); } /** * Assert the response status code is {@code HttpStatus.FOUND} (302). */ public ExchangeActions isFound() { - return doMatch(HttpStatus.FOUND); + return assertStatusIsEqualTo(HttpStatus.FOUND); } /** @@ -223,21 +235,21 @@ public class ResponseStatusAssertions { */ @Deprecated public ExchangeActions isMovedTemporarily() { - return doMatch(HttpStatus.MOVED_TEMPORARILY); + return assertStatusIsEqualTo(HttpStatus.MOVED_TEMPORARILY); } /** * Assert the response status code is {@code HttpStatus.SEE_OTHER} (303). */ public ExchangeActions isSeeOther() { - return doMatch(HttpStatus.SEE_OTHER); + return assertStatusIsEqualTo(HttpStatus.SEE_OTHER); } /** * Assert the response status code is {@code HttpStatus.NOT_MODIFIED} (304). */ public ExchangeActions isNotModified() { - return doMatch(HttpStatus.NOT_MODIFIED); + return assertStatusIsEqualTo(HttpStatus.NOT_MODIFIED); } /** @@ -246,112 +258,112 @@ public class ResponseStatusAssertions { */ @Deprecated public ExchangeActions isUseProxy() { - return doMatch(HttpStatus.USE_PROXY); + return assertStatusIsEqualTo(HttpStatus.USE_PROXY); } /** * Assert the response status code is {@code HttpStatus.TEMPORARY_REDIRECT} (307). */ public ExchangeActions isTemporaryRedirect() { - return doMatch(HttpStatus.TEMPORARY_REDIRECT); + return assertStatusIsEqualTo(HttpStatus.TEMPORARY_REDIRECT); } /** * Assert the response status code is {@code HttpStatus.PERMANENT_REDIRECT} (308). */ public ExchangeActions isPermanentRedirect() { - return doMatch(HttpStatus.valueOf(308)); + return assertStatusIsEqualTo(HttpStatus.valueOf(308)); } /** * Assert the response status code is {@code HttpStatus.BAD_REQUEST} (400). */ public ExchangeActions isBadRequest() { - return doMatch(HttpStatus.BAD_REQUEST); + return assertStatusIsEqualTo(HttpStatus.BAD_REQUEST); } /** * Assert the response status code is {@code HttpStatus.UNAUTHORIZED} (401). */ public ExchangeActions isUnauthorized() { - return doMatch(HttpStatus.UNAUTHORIZED); + return assertStatusIsEqualTo(HttpStatus.UNAUTHORIZED); } /** * Assert the response status code is {@code HttpStatus.PAYMENT_REQUIRED} (402). */ public ExchangeActions isPaymentRequired() { - return doMatch(HttpStatus.PAYMENT_REQUIRED); + return assertStatusIsEqualTo(HttpStatus.PAYMENT_REQUIRED); } /** * Assert the response status code is {@code HttpStatus.FORBIDDEN} (403). */ public ExchangeActions isForbidden() { - return doMatch(HttpStatus.FORBIDDEN); + return assertStatusIsEqualTo(HttpStatus.FORBIDDEN); } /** * Assert the response status code is {@code HttpStatus.NOT_FOUND} (404). */ public ExchangeActions isNotFound() { - return doMatch(HttpStatus.NOT_FOUND); + return assertStatusIsEqualTo(HttpStatus.NOT_FOUND); } /** * Assert the response status code is {@code HttpStatus.METHOD_NOT_ALLOWED} (405). */ public ExchangeActions isMethodNotAllowed() { - return doMatch(HttpStatus.METHOD_NOT_ALLOWED); + return assertStatusIsEqualTo(HttpStatus.METHOD_NOT_ALLOWED); } /** * Assert the response status code is {@code HttpStatus.NOT_ACCEPTABLE} (406). */ public ExchangeActions isNotAcceptable() { - return doMatch(HttpStatus.NOT_ACCEPTABLE); + return assertStatusIsEqualTo(HttpStatus.NOT_ACCEPTABLE); } /** * Assert the response status code is {@code HttpStatus.PROXY_AUTHENTICATION_REQUIRED} (407). */ public ExchangeActions isProxyAuthenticationRequired() { - return doMatch(HttpStatus.PROXY_AUTHENTICATION_REQUIRED); + return assertStatusIsEqualTo(HttpStatus.PROXY_AUTHENTICATION_REQUIRED); } /** * Assert the response status code is {@code HttpStatus.REQUEST_TIMEOUT} (408). */ public ExchangeActions isRequestTimeout() { - return doMatch(HttpStatus.REQUEST_TIMEOUT); + return assertStatusIsEqualTo(HttpStatus.REQUEST_TIMEOUT); } /** * Assert the response status code is {@code HttpStatus.CONFLICT} (409). */ public ExchangeActions isConflict() { - return doMatch(HttpStatus.CONFLICT); + return assertStatusIsEqualTo(HttpStatus.CONFLICT); } /** * Assert the response status code is {@code HttpStatus.GONE} (410). */ public ExchangeActions isGone() { - return doMatch(HttpStatus.GONE); + return assertStatusIsEqualTo(HttpStatus.GONE); } /** * Assert the response status code is {@code HttpStatus.LENGTH_REQUIRED} (411). */ public ExchangeActions isLengthRequired() { - return doMatch(HttpStatus.LENGTH_REQUIRED); + return assertStatusIsEqualTo(HttpStatus.LENGTH_REQUIRED); } /** * Assert the response status code is {@code HttpStatus.PRECONDITION_FAILED} (412). */ public ExchangeActions isPreconditionFailed() { - return doMatch(HttpStatus.PRECONDITION_FAILED); + return assertStatusIsEqualTo(HttpStatus.PRECONDITION_FAILED); } /** @@ -359,7 +371,7 @@ public class ResponseStatusAssertions { * @since 4.1 */ public ExchangeActions isPayloadTooLarge() { - return doMatch(HttpStatus.PAYLOAD_TOO_LARGE); + return assertStatusIsEqualTo(HttpStatus.PAYLOAD_TOO_LARGE); } /** @@ -369,7 +381,7 @@ public class ResponseStatusAssertions { */ @Deprecated public ExchangeActions isRequestEntityTooLarge() { - return doMatch(HttpStatus.REQUEST_ENTITY_TOO_LARGE); + return assertStatusIsEqualTo(HttpStatus.REQUEST_ENTITY_TOO_LARGE); } /** @@ -377,7 +389,7 @@ public class ResponseStatusAssertions { * @since 4.1 */ public ExchangeActions isUriTooLong() { - return doMatch(HttpStatus.URI_TOO_LONG); + return assertStatusIsEqualTo(HttpStatus.URI_TOO_LONG); } /** @@ -387,35 +399,35 @@ public class ResponseStatusAssertions { */ @Deprecated public ExchangeActions isRequestUriTooLong() { - return doMatch(HttpStatus.REQUEST_URI_TOO_LONG); + return assertStatusIsEqualTo(HttpStatus.REQUEST_URI_TOO_LONG); } /** * Assert the response status code is {@code HttpStatus.UNSUPPORTED_MEDIA_TYPE} (415). */ public ExchangeActions isUnsupportedMediaType() { - return doMatch(HttpStatus.UNSUPPORTED_MEDIA_TYPE); + return assertStatusIsEqualTo(HttpStatus.UNSUPPORTED_MEDIA_TYPE); } /** * Assert the response status code is {@code HttpStatus.REQUESTED_RANGE_NOT_SATISFIABLE} (416). */ public ExchangeActions isRequestedRangeNotSatisfiable() { - return doMatch(HttpStatus.REQUESTED_RANGE_NOT_SATISFIABLE); + return assertStatusIsEqualTo(HttpStatus.REQUESTED_RANGE_NOT_SATISFIABLE); } /** * Assert the response status code is {@code HttpStatus.EXPECTATION_FAILED} (417). */ public ExchangeActions isExpectationFailed() { - return doMatch(HttpStatus.EXPECTATION_FAILED); + return assertStatusIsEqualTo(HttpStatus.EXPECTATION_FAILED); } /** * Assert the response status code is {@code HttpStatus.I_AM_A_TEAPOT} (418). */ public ExchangeActions isIAmATeapot() { - return doMatch(HttpStatus.valueOf(418)); + return assertStatusIsEqualTo(HttpStatus.valueOf(418)); } /** @@ -424,7 +436,7 @@ public class ResponseStatusAssertions { */ @Deprecated public ExchangeActions isInsufficientSpaceOnResource() { - return doMatch(HttpStatus.INSUFFICIENT_SPACE_ON_RESOURCE); + return assertStatusIsEqualTo(HttpStatus.INSUFFICIENT_SPACE_ON_RESOURCE); } /** @@ -433,7 +445,7 @@ public class ResponseStatusAssertions { */ @Deprecated public ExchangeActions isMethodFailure() { - return doMatch(HttpStatus.METHOD_FAILURE); + return assertStatusIsEqualTo(HttpStatus.METHOD_FAILURE); } /** @@ -442,56 +454,56 @@ public class ResponseStatusAssertions { */ @Deprecated public ExchangeActions isDestinationLocked() { - return doMatch(HttpStatus.DESTINATION_LOCKED); + return assertStatusIsEqualTo(HttpStatus.DESTINATION_LOCKED); } /** * Assert the response status code is {@code HttpStatus.UNPROCESSABLE_ENTITY} (422). */ public ExchangeActions isUnprocessableEntity() { - return doMatch(HttpStatus.UNPROCESSABLE_ENTITY); + return assertStatusIsEqualTo(HttpStatus.UNPROCESSABLE_ENTITY); } /** * Assert the response status code is {@code HttpStatus.LOCKED} (423). */ public ExchangeActions isLocked() { - return doMatch(HttpStatus.LOCKED); + return assertStatusIsEqualTo(HttpStatus.LOCKED); } /** * Assert the response status code is {@code HttpStatus.FAILED_DEPENDENCY} (424). */ public ExchangeActions isFailedDependency() { - return doMatch(HttpStatus.FAILED_DEPENDENCY); + return assertStatusIsEqualTo(HttpStatus.FAILED_DEPENDENCY); } /** * Assert the response status code is {@code HttpStatus.UPGRADE_REQUIRED} (426). */ public ExchangeActions isUpgradeRequired() { - return doMatch(HttpStatus.UPGRADE_REQUIRED); + return assertStatusIsEqualTo(HttpStatus.UPGRADE_REQUIRED); } /** * Assert the response status code is {@code HttpStatus.PRECONDITION_REQUIRED} (428). */ public ExchangeActions isPreconditionRequired() { - return doMatch(HttpStatus.valueOf(428)); + return assertStatusIsEqualTo(HttpStatus.valueOf(428)); } /** * Assert the response status code is {@code HttpStatus.TOO_MANY_REQUESTS} (429). */ public ExchangeActions isTooManyRequests() { - return doMatch(HttpStatus.valueOf(429)); + return assertStatusIsEqualTo(HttpStatus.valueOf(429)); } /** * Assert the response status code is {@code HttpStatus.REQUEST_HEADER_FIELDS_TOO_LARGE} (431). */ public ExchangeActions isRequestHeaderFieldsTooLarge() { - return doMatch(HttpStatus.valueOf(431)); + return assertStatusIsEqualTo(HttpStatus.valueOf(431)); } /** @@ -499,94 +511,94 @@ public class ResponseStatusAssertions { * @since 4.3 */ public ExchangeActions isUnavailableForLegalReasons() { - return doMatch(HttpStatus.valueOf(451)); + return assertStatusIsEqualTo(HttpStatus.valueOf(451)); } /** * Assert the response status code is {@code HttpStatus.INTERNAL_SERVER_ERROR} (500). */ public ExchangeActions isInternalServerError() { - return doMatch(HttpStatus.INTERNAL_SERVER_ERROR); + return assertStatusIsEqualTo(HttpStatus.INTERNAL_SERVER_ERROR); } /** * Assert the response status code is {@code HttpStatus.NOT_IMPLEMENTED} (501). */ public ExchangeActions isNotImplemented() { - return doMatch(HttpStatus.NOT_IMPLEMENTED); + return assertStatusIsEqualTo(HttpStatus.NOT_IMPLEMENTED); } /** * Assert the response status code is {@code HttpStatus.BAD_GATEWAY} (502). */ public ExchangeActions isBadGateway() { - return doMatch(HttpStatus.BAD_GATEWAY); + return assertStatusIsEqualTo(HttpStatus.BAD_GATEWAY); } /** * Assert the response status code is {@code HttpStatus.SERVICE_UNAVAILABLE} (503). */ public ExchangeActions isServiceUnavailable() { - return doMatch(HttpStatus.SERVICE_UNAVAILABLE); + return assertStatusIsEqualTo(HttpStatus.SERVICE_UNAVAILABLE); } /** * Assert the response status code is {@code HttpStatus.GATEWAY_TIMEOUT} (504). */ public ExchangeActions isGatewayTimeout() { - return doMatch(HttpStatus.GATEWAY_TIMEOUT); + return assertStatusIsEqualTo(HttpStatus.GATEWAY_TIMEOUT); } /** * Assert the response status code is {@code HttpStatus.HTTP_VERSION_NOT_SUPPORTED} (505). */ public ExchangeActions isHttpVersionNotSupported() { - return doMatch(HttpStatus.HTTP_VERSION_NOT_SUPPORTED); + return assertStatusIsEqualTo(HttpStatus.HTTP_VERSION_NOT_SUPPORTED); } /** * Assert the response status code is {@code HttpStatus.VARIANT_ALSO_NEGOTIATES} (506). */ public ExchangeActions isVariantAlsoNegotiates() { - return doMatch(HttpStatus.VARIANT_ALSO_NEGOTIATES); + return assertStatusIsEqualTo(HttpStatus.VARIANT_ALSO_NEGOTIATES); } /** * Assert the response status code is {@code HttpStatus.INSUFFICIENT_STORAGE} (507). */ public ExchangeActions isInsufficientStorage() { - return doMatch(HttpStatus.INSUFFICIENT_STORAGE); + return assertStatusIsEqualTo(HttpStatus.INSUFFICIENT_STORAGE); } /** * Assert the response status code is {@code HttpStatus.LOOP_DETECTED} (508). */ public ExchangeActions isLoopDetected() { - return doMatch(HttpStatus.LOOP_DETECTED); + return assertStatusIsEqualTo(HttpStatus.LOOP_DETECTED); } /** * Assert the response status code is {@code HttpStatus.BANDWIDTH_LIMIT_EXCEEDED} (509). */ public ExchangeActions isBandwidthLimitExceeded() { - return doMatch(HttpStatus.valueOf(509)); + return assertStatusIsEqualTo(HttpStatus.valueOf(509)); } /** * Assert the response status code is {@code HttpStatus.NOT_EXTENDED} (510). */ public ExchangeActions isNotExtended() { - return doMatch(HttpStatus.NOT_EXTENDED); + return assertStatusIsEqualTo(HttpStatus.NOT_EXTENDED); } /** * Assert the response status code is {@code HttpStatus.NETWORK_AUTHENTICATION_REQUIRED} (511). */ public ExchangeActions isNetworkAuthenticationRequired() { - return doMatch(HttpStatus.valueOf(511)); + return assertStatusIsEqualTo(HttpStatus.valueOf(511)); } - private ExchangeActions doMatch(final HttpStatus status) { + private ExchangeActions assertStatusIsEqualTo(final HttpStatus status) { assertEquals("Status", status, this.httpStatus); return this.exchangeActions; } diff --git a/spring-test/src/test/java/org/springframework/test/web/reactive/server/samples/HeaderTests.java b/spring-test/src/test/java/org/springframework/test/web/reactive/server/samples/HeaderTests.java index 8f47199b941..9cbe8b8f157 100644 --- a/spring-test/src/test/java/org/springframework/test/web/reactive/server/samples/HeaderTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/reactive/server/samples/HeaderTests.java @@ -15,6 +15,8 @@ */ package org.springframework.test.web.reactive.server.samples; +import java.util.Arrays; + import org.junit.Before; import org.junit.Test; @@ -22,8 +24,11 @@ import org.springframework.http.ResponseEntity; import org.springframework.test.web.reactive.server.WebTestClient; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestHeader; +import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +import static org.junit.Assert.assertEquals; + /** * Tests with custom headers. * @@ -37,27 +42,45 @@ public class HeaderTests { @Before public void setUp() throws Exception { - this.client = WebTestClient.bindToController(new TestController()).build(); + this.client = WebTestClient + .bindToController(new TestController()) + .webClientSpec().baseUrl("/header") + .build(); } @Test - public void customHeader() throws Exception { - this.client.get().uri("/header").header("h1", "ping") + public void requestResponseHeaderPair() throws Exception { + this.client.get().uri("/request-response-pair").header("h1", "in") .exchange() .assertStatus().isOk() - .assertHeader("h1").isEqualTo("ping-pong"); + .assertHeader("h1").isEqualTo("in-out"); + } + + @Test + public void headerConsumer() throws Exception { + this.client.get().uri("/multivalue") + .exchange() + .assertStatus().isOk() + .assertHeader("h1").consume(value -> assertEquals("v1", value)) + .assertHeader("h1").values().consume(values -> assertEquals(Arrays.asList("v1", "v2", "v3"), values)); } @RestController + @RequestMapping("header") static class TestController { - @GetMapping("header") + @GetMapping("request-response-pair") ResponseEntity handleHeader(@RequestHeader("h1") String myHeader) { - String value = myHeader + "-pong"; + String value = myHeader + "-out"; return ResponseEntity.ok().header("h1", value).build(); } + + @GetMapping("multivalue") + ResponseEntity multivalue() { + return ResponseEntity.ok().header("h1", "v1", "v2", "v3").build(); + } } } diff --git a/spring-test/src/test/java/org/springframework/test/web/reactive/server/samples/ResponseEntityTests.java b/spring-test/src/test/java/org/springframework/test/web/reactive/server/samples/ResponseEntityTests.java index d56425855cc..101cd12d007 100644 --- a/spring-test/src/test/java/org/springframework/test/web/reactive/server/samples/ResponseEntityTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/reactive/server/samples/ResponseEntityTests.java @@ -16,6 +16,8 @@ package org.springframework.test.web.reactive.server.samples; import java.net.URI; +import java.util.LinkedHashMap; +import java.util.Map; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; @@ -35,6 +37,7 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import static org.hamcrest.CoreMatchers.endsWith; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertThat; import static org.springframework.http.MediaType.TEXT_EVENT_STREAM; @@ -65,7 +68,7 @@ public class ResponseEntityTests { } @Test - public void entityCollection() throws Exception { + public void entityList() throws Exception { this.client.get().uri("/persons") .exchange() .assertStatus().isOk() @@ -75,6 +78,14 @@ public class ResponseEntityTests { .contains(new Person("Jane"), new Person("Jason"), new Person("John")); } + @Test + public void entityMap() throws Exception { + this.client.get().uri("/persons?map=true") + .exchange() + .assertStatus().isOk() + .assertEntity(Person.class).map().hasSize(3).containsKeys("Jane", "Jason", "John"); + } + @Test public void entityStream() throws Exception { this.client.get().uri("/persons").accept(TEXT_EVENT_STREAM) @@ -90,7 +101,7 @@ public class ResponseEntityTests { } @Test - public void saveEntity() throws Exception { + public void postEntity() throws Exception { this.client.post().uri("/persons") .exchange(Mono.just(new Person("John")), Person.class) .assertStatus().isCreated() @@ -98,6 +109,14 @@ public class ResponseEntityTests { .assertBody().isEmpty(); } + @Test + public void entityConsumer() throws Exception { + this.client.get().uri("/persons/John") + .exchange() + .assertStatus().isOk() + .assertEntity(Person.class).consume(p -> assertEquals(new Person("John"), p)); + } + @RestController @RequestMapping("/persons") @@ -113,6 +132,15 @@ public class ResponseEntityTests { return Flux.just(new Person("Jane"), new Person("Jason"), new Person("John")); } + @GetMapping(params = "map") + Map getPersonsAsMap() { + Map map = new LinkedHashMap<>(); + map.put("Jane", new Person("Jane")); + map.put("Jason", new Person("Jason")); + map.put("John", new Person("John")); + return map; + } + @GetMapping(produces = "text/event-stream") Flux getPersonStream() { return Flux.intervalMillis(100).onBackpressureBuffer(10).map(index -> new Person("N" + index));