Updates to ExchangeActions

Add assertEntity(Foo.class).map() -> Map<String, Foo>

Add assertBody().map() -> Map<String, String>

Rename andAssert(Consumer<?>) to "consume" in assertion classes

Remove andAssert + andDo from top-level ExchangeActions
This commit is contained in:
Rossen Stoyanchev 2017-02-13 20:37:42 -05:00
parent 656e7f801e
commit 130598ffb2
8 changed files with 185 additions and 145 deletions

View File

@ -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 <T> ResponseEntityAssertions<T> assertEntity(Class<T> entityType) {
return new ResponseEntityAssertions<T>(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 <T> ResponseEntityAssertions<T> assertEntity(Class<T> entityType) {
return assertEntity(ResolvableType.forClass(entityType));
}
/**
* Assert the content of the response.
* @return further options for asserting response entities
*/
public <T> ResponseEntityAssertions<T> assertEntity(ResolvableType entityType) {
return new ResponseEntityAssertions<T>(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.
* <p>Consider using statically imported methods to improve readability
* @param consumer consumer that will apply assertions.
*/
public ExchangeActions andAssert(Consumer<ExchangeInfo> consumer) {
consumer.accept(this.exchangeInfo);
return this;
}
/**
* Apply custom actions on the performed exchange.
* <p>Consider using statically imported methods to improve readability
* @param consumer consumer that will apply the custom action
*/
public ExchangeActions andDo(Consumer<ExchangeInfo> consumer) {
consumer.accept(this.exchangeInfo);
return this;
}
/**
* Return {@link ExchangeInfo} for direct access to request and response.
*/

View File

@ -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<V, S extends ObjectAssertions<V, S>> {
}
/**
* Apply custom assertions on the Object value with the help of
* {@link AssertionErrors} or an assertion library such as AssertJ.
* <p>Consider using statically imported methods for creating the assertion
* consumer to improve readability of tests.
* @param assertionConsumer consumer that will apply assertions.
*/
public <T extends S> T andAssert(Consumer<V> assertionConsumer) {
assertionConsumer.accept(getValue());
return self();
}
/**
* Apply custom actions on the Object value.
* <p>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}.
* <p>Consider using statically imported methods to improve readability
* @param consumer consumer that will apply the custom action
*/
public <T extends S> T andDo(Consumer<V> consumer) {
consumer.accept(getValue());
return self();
public ExchangeActions consume(Consumer<V> consumer) {
consumer.accept(this.getValue());
return this.exchangeActions;
}
/**
* Continue with more assertions or actions on the response.
*/

View File

@ -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 <K, V> MapAssertions<K, V> asMap(Class<K> keyType, Class<V> valueType) {
ResolvableType type = ResolvableType.forClassWithGenerics(Map.class, keyType, valueType);
Mono<Map<K, V>> mono = getResponse().body(toMono(type));
Map<K, V> map = mono.block(getTimeout());
public MapAssertions<String, String> asMap() {
ResolvableType type = ResolvableType.forClassWithGenerics(Map.class, String.class, String.class);
Mono<Map<String, String>> mono = getResponse().body(toMono(type));
Map<String, String> map = mono.block(getTimeout());
return new MapAssertions<>(this.exchangeActions, map, "Response body map");
}

View File

@ -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 <T> the response entity type
*
* @author Rossen Stoyanchev
* @sine 5.0
* @since 5.0
*/
public class ResponseEntityAssertions<T> extends ObjectAssertions<T, ResponseEntityAssertions<T>> {
@ -60,6 +61,17 @@ public class ResponseEntityAssertions<T> extends ObjectAssertions<T, ResponseEnt
return new ListAssertions<T>(getExchangeActions(), list, "Response entity collection");
}
/**
* Assert the response decoded as a Map of entities with String keys.
*/
public MapAssertions<String, T> map() {
ResolvableType keyType = ResolvableType.forClass(String.class);
ResolvableType type = ResolvableType.forClassWithGenerics(Map.class, keyType, this.entityType);
Mono<Map<String, T>> mono = getResponse().body(toMono(type));
Map<String, T> map = mono.block(getTimeout());
return new MapAssertions<>(getExchangeActions(), map, "Response entity map");
}
/**
* Assert the response content using a {@link StepVerifier}.
*/

View File

@ -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}.
* <p>Consider using statically imported methods to improve readability
* @param consumer consumer that will apply the custom action
*/
public ExchangeActions consume(Consumer<HttpHeaders> consumer) {
consumer.accept(this.headers);
return this.exchangeActions;
}
}

View File

@ -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}.
* <p>Consider using statically imported methods to improve readability
* @param consumer consumer that will apply the custom action
*/
public ExchangeActions consume(Consumer<HttpStatus> 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;
}

View File

@ -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<Void> handleHeader(@RequestHeader("h1") String myHeader) {
String value = myHeader + "-pong";
String value = myHeader + "-out";
return ResponseEntity.ok().header("h1", value).build();
}
@GetMapping("multivalue")
ResponseEntity<Void> multivalue() {
return ResponseEntity.ok().header("h1", "v1", "v2", "v3").build();
}
}
}

View File

@ -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<String, Person> getPersonsAsMap() {
Map<String, Person> 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<Person> getPersonStream() {
return Flux.intervalMillis(100).onBackpressureBuffer(10).map(index -> new Person("N" + index));