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; package org.springframework.test.web.reactive.server;
import java.time.Duration;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.function.Consumer;
import org.springframework.core.ResolvableType; import org.springframework.core.ResolvableType;
import org.springframework.http.HttpHeaders; 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. * 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() { public ResponseBodyAssertions assertBody() {
return new ResponseBodyAssertions(this); 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. * Log debug information about the exchange.
*/ */
@ -99,27 +88,6 @@ public final class ExchangeActions {
return new LoggingExchangeConsumer(this); 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. * 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.Consumer;
import java.util.function.Supplier; import java.util.function.Supplier;
import org.springframework.test.util.AssertionErrors;
import org.springframework.web.reactive.function.client.ClientResponse; import org.springframework.web.reactive.function.client.ClientResponse;
import static org.springframework.test.util.AssertionErrors.assertEquals; 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 * Custom assertions on the Object value with a {@link Consumer}.
* {@link AssertionErrors} or an assertion library such as AssertJ. * <p>Consider using statically imported methods to improve readability
* <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.
* @param consumer consumer that will apply the custom action * @param consumer consumer that will apply the custom action
*/ */
public <T extends S> T andDo(Consumer<V> consumer) { public ExchangeActions consume(Consumer<V> consumer) {
consumer.accept(getValue()); consumer.accept(this.getValue());
return self(); return this.exchangeActions;
} }
/** /**
* Continue with more assertions or actions on the response. * 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; import static org.springframework.web.reactive.function.BodyExtractors.toMono;
/** /**
* Assertions on the body of the response.
* *
* @author Rossen Stoyanchev * @author Rossen Stoyanchev
* @since 5.0 * @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) { public MapAssertions<String, String> asMap() {
ResolvableType type = ResolvableType.forClassWithGenerics(Map.class, keyType, valueType); ResolvableType type = ResolvableType.forClassWithGenerics(Map.class, String.class, String.class);
Mono<Map<K, V>> mono = getResponse().body(toMono(type)); Mono<Map<String, String>> mono = getResponse().body(toMono(type));
Map<K, V> map = mono.block(getTimeout()); Map<String, String> map = mono.block(getTimeout());
return new MapAssertions<>(this.exchangeActions, map, "Response body map"); return new MapAssertions<>(this.exchangeActions, map, "Response body map");
} }

View File

@ -16,6 +16,7 @@
package org.springframework.test.web.reactive.server; package org.springframework.test.web.reactive.server;
import java.util.List; import java.util.List;
import java.util.Map;
import reactor.core.publisher.Flux; import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono; import reactor.core.publisher.Mono;
@ -32,7 +33,7 @@ import static org.springframework.web.reactive.function.BodyExtractors.toMono;
* @param <T> the response entity type * @param <T> the response entity type
* *
* @author Rossen Stoyanchev * @author Rossen Stoyanchev
* @sine 5.0 * @since 5.0
*/ */
public class ResponseEntityAssertions<T> extends ObjectAssertions<T, ResponseEntityAssertions<T>> { 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"); 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}. * Assert the response content using a {@link StepVerifier}.
*/ */

View File

@ -15,8 +15,7 @@
*/ */
package org.springframework.test.web.reactive.server; package org.springframework.test.web.reactive.server;
import java.util.Collections; import java.util.function.Consumer;
import java.util.List;
import org.springframework.http.CacheControl; import org.springframework.http.CacheControl;
import org.springframework.http.ContentDisposition; import org.springframework.http.ContentDisposition;
@ -80,4 +79,14 @@ public class ResponseHeadersAssertions {
return this.exchangeActions; 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; package org.springframework.test.web.reactive.server;
import java.util.function.Consumer;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import static org.springframework.test.util.AssertionErrors.assertEquals; import static org.springframework.test.util.AssertionErrors.assertEquals;
@ -89,6 +91,16 @@ public class ResponseStatusAssertions {
return this.exchangeActions; 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. * Assert the response error message.
*/ */
@ -101,119 +113,119 @@ public class ResponseStatusAssertions {
* Assert the response status code is {@code HttpStatus.CONTINUE} (100). * Assert the response status code is {@code HttpStatus.CONTINUE} (100).
*/ */
public ExchangeActions isContinue() { public ExchangeActions isContinue() {
return doMatch(HttpStatus.CONTINUE); return assertStatusIsEqualTo(HttpStatus.CONTINUE);
} }
/** /**
* Assert the response status code is {@code HttpStatus.SWITCHING_PROTOCOLS} (101). * Assert the response status code is {@code HttpStatus.SWITCHING_PROTOCOLS} (101).
*/ */
public ExchangeActions isSwitchingProtocols() { public ExchangeActions isSwitchingProtocols() {
return doMatch(HttpStatus.SWITCHING_PROTOCOLS); return assertStatusIsEqualTo(HttpStatus.SWITCHING_PROTOCOLS);
} }
/** /**
* Assert the response status code is {@code HttpStatus.PROCESSING} (102). * Assert the response status code is {@code HttpStatus.PROCESSING} (102).
*/ */
public ExchangeActions isProcessing() { public ExchangeActions isProcessing() {
return doMatch(HttpStatus.PROCESSING); return assertStatusIsEqualTo(HttpStatus.PROCESSING);
} }
/** /**
* Assert the response status code is {@code HttpStatus.CHECKPOINT} (103). * Assert the response status code is {@code HttpStatus.CHECKPOINT} (103).
*/ */
public ExchangeActions isCheckpoint() { public ExchangeActions isCheckpoint() {
return doMatch(HttpStatus.valueOf(103)); return assertStatusIsEqualTo(HttpStatus.valueOf(103));
} }
/** /**
* Assert the response status code is {@code HttpStatus.OK} (200). * Assert the response status code is {@code HttpStatus.OK} (200).
*/ */
public ExchangeActions isOk() { public ExchangeActions isOk() {
return doMatch(HttpStatus.OK); return assertStatusIsEqualTo(HttpStatus.OK);
} }
/** /**
* Assert the response status code is {@code HttpStatus.CREATED} (201). * Assert the response status code is {@code HttpStatus.CREATED} (201).
*/ */
public ExchangeActions isCreated() { public ExchangeActions isCreated() {
return doMatch(HttpStatus.CREATED); return assertStatusIsEqualTo(HttpStatus.CREATED);
} }
/** /**
* Assert the response status code is {@code HttpStatus.ACCEPTED} (202). * Assert the response status code is {@code HttpStatus.ACCEPTED} (202).
*/ */
public ExchangeActions isAccepted() { public ExchangeActions isAccepted() {
return doMatch(HttpStatus.ACCEPTED); return assertStatusIsEqualTo(HttpStatus.ACCEPTED);
} }
/** /**
* Assert the response status code is {@code HttpStatus.NON_AUTHORITATIVE_INFORMATION} (203). * Assert the response status code is {@code HttpStatus.NON_AUTHORITATIVE_INFORMATION} (203).
*/ */
public ExchangeActions isNonAuthoritativeInformation() { 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). * Assert the response status code is {@code HttpStatus.NO_CONTENT} (204).
*/ */
public ExchangeActions isNoContent() { public ExchangeActions isNoContent() {
return doMatch(HttpStatus.NO_CONTENT); return assertStatusIsEqualTo(HttpStatus.NO_CONTENT);
} }
/** /**
* Assert the response status code is {@code HttpStatus.RESET_CONTENT} (205). * Assert the response status code is {@code HttpStatus.RESET_CONTENT} (205).
*/ */
public ExchangeActions isResetContent() { public ExchangeActions isResetContent() {
return doMatch(HttpStatus.RESET_CONTENT); return assertStatusIsEqualTo(HttpStatus.RESET_CONTENT);
} }
/** /**
* Assert the response status code is {@code HttpStatus.PARTIAL_CONTENT} (206). * Assert the response status code is {@code HttpStatus.PARTIAL_CONTENT} (206).
*/ */
public ExchangeActions isPartialContent() { public ExchangeActions isPartialContent() {
return doMatch(HttpStatus.PARTIAL_CONTENT); return assertStatusIsEqualTo(HttpStatus.PARTIAL_CONTENT);
} }
/** /**
* Assert the response status code is {@code HttpStatus.MULTI_STATUS} (207). * Assert the response status code is {@code HttpStatus.MULTI_STATUS} (207).
*/ */
public ExchangeActions isMultiStatus() { public ExchangeActions isMultiStatus() {
return doMatch(HttpStatus.MULTI_STATUS); return assertStatusIsEqualTo(HttpStatus.MULTI_STATUS);
} }
/** /**
* Assert the response status code is {@code HttpStatus.ALREADY_REPORTED} (208). * Assert the response status code is {@code HttpStatus.ALREADY_REPORTED} (208).
*/ */
public ExchangeActions isAlreadyReported() { public ExchangeActions isAlreadyReported() {
return doMatch(HttpStatus.ALREADY_REPORTED); return assertStatusIsEqualTo(HttpStatus.ALREADY_REPORTED);
} }
/** /**
* Assert the response status code is {@code HttpStatus.IM_USED} (226). * Assert the response status code is {@code HttpStatus.IM_USED} (226).
*/ */
public ExchangeActions isImUsed() { public ExchangeActions isImUsed() {
return doMatch(HttpStatus.IM_USED); return assertStatusIsEqualTo(HttpStatus.IM_USED);
} }
/** /**
* Assert the response status code is {@code HttpStatus.MULTIPLE_CHOICES} (300). * Assert the response status code is {@code HttpStatus.MULTIPLE_CHOICES} (300).
*/ */
public ExchangeActions isMultipleChoices() { public ExchangeActions isMultipleChoices() {
return doMatch(HttpStatus.MULTIPLE_CHOICES); return assertStatusIsEqualTo(HttpStatus.MULTIPLE_CHOICES);
} }
/** /**
* Assert the response status code is {@code HttpStatus.MOVED_PERMANENTLY} (301). * Assert the response status code is {@code HttpStatus.MOVED_PERMANENTLY} (301).
*/ */
public ExchangeActions isMovedPermanently() { public ExchangeActions isMovedPermanently() {
return doMatch(HttpStatus.MOVED_PERMANENTLY); return assertStatusIsEqualTo(HttpStatus.MOVED_PERMANENTLY);
} }
/** /**
* Assert the response status code is {@code HttpStatus.FOUND} (302). * Assert the response status code is {@code HttpStatus.FOUND} (302).
*/ */
public ExchangeActions isFound() { public ExchangeActions isFound() {
return doMatch(HttpStatus.FOUND); return assertStatusIsEqualTo(HttpStatus.FOUND);
} }
/** /**
@ -223,21 +235,21 @@ public class ResponseStatusAssertions {
*/ */
@Deprecated @Deprecated
public ExchangeActions isMovedTemporarily() { public ExchangeActions isMovedTemporarily() {
return doMatch(HttpStatus.MOVED_TEMPORARILY); return assertStatusIsEqualTo(HttpStatus.MOVED_TEMPORARILY);
} }
/** /**
* Assert the response status code is {@code HttpStatus.SEE_OTHER} (303). * Assert the response status code is {@code HttpStatus.SEE_OTHER} (303).
*/ */
public ExchangeActions isSeeOther() { public ExchangeActions isSeeOther() {
return doMatch(HttpStatus.SEE_OTHER); return assertStatusIsEqualTo(HttpStatus.SEE_OTHER);
} }
/** /**
* Assert the response status code is {@code HttpStatus.NOT_MODIFIED} (304). * Assert the response status code is {@code HttpStatus.NOT_MODIFIED} (304).
*/ */
public ExchangeActions isNotModified() { public ExchangeActions isNotModified() {
return doMatch(HttpStatus.NOT_MODIFIED); return assertStatusIsEqualTo(HttpStatus.NOT_MODIFIED);
} }
/** /**
@ -246,112 +258,112 @@ public class ResponseStatusAssertions {
*/ */
@Deprecated @Deprecated
public ExchangeActions isUseProxy() { public ExchangeActions isUseProxy() {
return doMatch(HttpStatus.USE_PROXY); return assertStatusIsEqualTo(HttpStatus.USE_PROXY);
} }
/** /**
* Assert the response status code is {@code HttpStatus.TEMPORARY_REDIRECT} (307). * Assert the response status code is {@code HttpStatus.TEMPORARY_REDIRECT} (307).
*/ */
public ExchangeActions isTemporaryRedirect() { public ExchangeActions isTemporaryRedirect() {
return doMatch(HttpStatus.TEMPORARY_REDIRECT); return assertStatusIsEqualTo(HttpStatus.TEMPORARY_REDIRECT);
} }
/** /**
* Assert the response status code is {@code HttpStatus.PERMANENT_REDIRECT} (308). * Assert the response status code is {@code HttpStatus.PERMANENT_REDIRECT} (308).
*/ */
public ExchangeActions isPermanentRedirect() { public ExchangeActions isPermanentRedirect() {
return doMatch(HttpStatus.valueOf(308)); return assertStatusIsEqualTo(HttpStatus.valueOf(308));
} }
/** /**
* Assert the response status code is {@code HttpStatus.BAD_REQUEST} (400). * Assert the response status code is {@code HttpStatus.BAD_REQUEST} (400).
*/ */
public ExchangeActions isBadRequest() { public ExchangeActions isBadRequest() {
return doMatch(HttpStatus.BAD_REQUEST); return assertStatusIsEqualTo(HttpStatus.BAD_REQUEST);
} }
/** /**
* Assert the response status code is {@code HttpStatus.UNAUTHORIZED} (401). * Assert the response status code is {@code HttpStatus.UNAUTHORIZED} (401).
*/ */
public ExchangeActions isUnauthorized() { public ExchangeActions isUnauthorized() {
return doMatch(HttpStatus.UNAUTHORIZED); return assertStatusIsEqualTo(HttpStatus.UNAUTHORIZED);
} }
/** /**
* Assert the response status code is {@code HttpStatus.PAYMENT_REQUIRED} (402). * Assert the response status code is {@code HttpStatus.PAYMENT_REQUIRED} (402).
*/ */
public ExchangeActions isPaymentRequired() { public ExchangeActions isPaymentRequired() {
return doMatch(HttpStatus.PAYMENT_REQUIRED); return assertStatusIsEqualTo(HttpStatus.PAYMENT_REQUIRED);
} }
/** /**
* Assert the response status code is {@code HttpStatus.FORBIDDEN} (403). * Assert the response status code is {@code HttpStatus.FORBIDDEN} (403).
*/ */
public ExchangeActions isForbidden() { public ExchangeActions isForbidden() {
return doMatch(HttpStatus.FORBIDDEN); return assertStatusIsEqualTo(HttpStatus.FORBIDDEN);
} }
/** /**
* Assert the response status code is {@code HttpStatus.NOT_FOUND} (404). * Assert the response status code is {@code HttpStatus.NOT_FOUND} (404).
*/ */
public ExchangeActions isNotFound() { 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). * Assert the response status code is {@code HttpStatus.METHOD_NOT_ALLOWED} (405).
*/ */
public ExchangeActions isMethodNotAllowed() { 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). * Assert the response status code is {@code HttpStatus.NOT_ACCEPTABLE} (406).
*/ */
public ExchangeActions isNotAcceptable() { 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). * Assert the response status code is {@code HttpStatus.PROXY_AUTHENTICATION_REQUIRED} (407).
*/ */
public ExchangeActions isProxyAuthenticationRequired() { 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). * Assert the response status code is {@code HttpStatus.REQUEST_TIMEOUT} (408).
*/ */
public ExchangeActions isRequestTimeout() { public ExchangeActions isRequestTimeout() {
return doMatch(HttpStatus.REQUEST_TIMEOUT); return assertStatusIsEqualTo(HttpStatus.REQUEST_TIMEOUT);
} }
/** /**
* Assert the response status code is {@code HttpStatus.CONFLICT} (409). * Assert the response status code is {@code HttpStatus.CONFLICT} (409).
*/ */
public ExchangeActions isConflict() { public ExchangeActions isConflict() {
return doMatch(HttpStatus.CONFLICT); return assertStatusIsEqualTo(HttpStatus.CONFLICT);
} }
/** /**
* Assert the response status code is {@code HttpStatus.GONE} (410). * Assert the response status code is {@code HttpStatus.GONE} (410).
*/ */
public ExchangeActions isGone() { public ExchangeActions isGone() {
return doMatch(HttpStatus.GONE); return assertStatusIsEqualTo(HttpStatus.GONE);
} }
/** /**
* Assert the response status code is {@code HttpStatus.LENGTH_REQUIRED} (411). * Assert the response status code is {@code HttpStatus.LENGTH_REQUIRED} (411).
*/ */
public ExchangeActions isLengthRequired() { public ExchangeActions isLengthRequired() {
return doMatch(HttpStatus.LENGTH_REQUIRED); return assertStatusIsEqualTo(HttpStatus.LENGTH_REQUIRED);
} }
/** /**
* Assert the response status code is {@code HttpStatus.PRECONDITION_FAILED} (412). * Assert the response status code is {@code HttpStatus.PRECONDITION_FAILED} (412).
*/ */
public ExchangeActions isPreconditionFailed() { public ExchangeActions isPreconditionFailed() {
return doMatch(HttpStatus.PRECONDITION_FAILED); return assertStatusIsEqualTo(HttpStatus.PRECONDITION_FAILED);
} }
/** /**
@ -359,7 +371,7 @@ public class ResponseStatusAssertions {
* @since 4.1 * @since 4.1
*/ */
public ExchangeActions isPayloadTooLarge() { public ExchangeActions isPayloadTooLarge() {
return doMatch(HttpStatus.PAYLOAD_TOO_LARGE); return assertStatusIsEqualTo(HttpStatus.PAYLOAD_TOO_LARGE);
} }
/** /**
@ -369,7 +381,7 @@ public class ResponseStatusAssertions {
*/ */
@Deprecated @Deprecated
public ExchangeActions isRequestEntityTooLarge() { 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 * @since 4.1
*/ */
public ExchangeActions isUriTooLong() { public ExchangeActions isUriTooLong() {
return doMatch(HttpStatus.URI_TOO_LONG); return assertStatusIsEqualTo(HttpStatus.URI_TOO_LONG);
} }
/** /**
@ -387,35 +399,35 @@ public class ResponseStatusAssertions {
*/ */
@Deprecated @Deprecated
public ExchangeActions isRequestUriTooLong() { 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). * Assert the response status code is {@code HttpStatus.UNSUPPORTED_MEDIA_TYPE} (415).
*/ */
public ExchangeActions isUnsupportedMediaType() { 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). * Assert the response status code is {@code HttpStatus.REQUESTED_RANGE_NOT_SATISFIABLE} (416).
*/ */
public ExchangeActions isRequestedRangeNotSatisfiable() { 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). * Assert the response status code is {@code HttpStatus.EXPECTATION_FAILED} (417).
*/ */
public ExchangeActions isExpectationFailed() { 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). * Assert the response status code is {@code HttpStatus.I_AM_A_TEAPOT} (418).
*/ */
public ExchangeActions isIAmATeapot() { public ExchangeActions isIAmATeapot() {
return doMatch(HttpStatus.valueOf(418)); return assertStatusIsEqualTo(HttpStatus.valueOf(418));
} }
/** /**
@ -424,7 +436,7 @@ public class ResponseStatusAssertions {
*/ */
@Deprecated @Deprecated
public ExchangeActions isInsufficientSpaceOnResource() { 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 @Deprecated
public ExchangeActions isMethodFailure() { public ExchangeActions isMethodFailure() {
return doMatch(HttpStatus.METHOD_FAILURE); return assertStatusIsEqualTo(HttpStatus.METHOD_FAILURE);
} }
/** /**
@ -442,56 +454,56 @@ public class ResponseStatusAssertions {
*/ */
@Deprecated @Deprecated
public ExchangeActions isDestinationLocked() { public ExchangeActions isDestinationLocked() {
return doMatch(HttpStatus.DESTINATION_LOCKED); return assertStatusIsEqualTo(HttpStatus.DESTINATION_LOCKED);
} }
/** /**
* Assert the response status code is {@code HttpStatus.UNPROCESSABLE_ENTITY} (422). * Assert the response status code is {@code HttpStatus.UNPROCESSABLE_ENTITY} (422).
*/ */
public ExchangeActions isUnprocessableEntity() { public ExchangeActions isUnprocessableEntity() {
return doMatch(HttpStatus.UNPROCESSABLE_ENTITY); return assertStatusIsEqualTo(HttpStatus.UNPROCESSABLE_ENTITY);
} }
/** /**
* Assert the response status code is {@code HttpStatus.LOCKED} (423). * Assert the response status code is {@code HttpStatus.LOCKED} (423).
*/ */
public ExchangeActions isLocked() { public ExchangeActions isLocked() {
return doMatch(HttpStatus.LOCKED); return assertStatusIsEqualTo(HttpStatus.LOCKED);
} }
/** /**
* Assert the response status code is {@code HttpStatus.FAILED_DEPENDENCY} (424). * Assert the response status code is {@code HttpStatus.FAILED_DEPENDENCY} (424).
*/ */
public ExchangeActions isFailedDependency() { public ExchangeActions isFailedDependency() {
return doMatch(HttpStatus.FAILED_DEPENDENCY); return assertStatusIsEqualTo(HttpStatus.FAILED_DEPENDENCY);
} }
/** /**
* Assert the response status code is {@code HttpStatus.UPGRADE_REQUIRED} (426). * Assert the response status code is {@code HttpStatus.UPGRADE_REQUIRED} (426).
*/ */
public ExchangeActions isUpgradeRequired() { public ExchangeActions isUpgradeRequired() {
return doMatch(HttpStatus.UPGRADE_REQUIRED); return assertStatusIsEqualTo(HttpStatus.UPGRADE_REQUIRED);
} }
/** /**
* Assert the response status code is {@code HttpStatus.PRECONDITION_REQUIRED} (428). * Assert the response status code is {@code HttpStatus.PRECONDITION_REQUIRED} (428).
*/ */
public ExchangeActions isPreconditionRequired() { 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). * Assert the response status code is {@code HttpStatus.TOO_MANY_REQUESTS} (429).
*/ */
public ExchangeActions isTooManyRequests() { 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). * Assert the response status code is {@code HttpStatus.REQUEST_HEADER_FIELDS_TOO_LARGE} (431).
*/ */
public ExchangeActions isRequestHeaderFieldsTooLarge() { public ExchangeActions isRequestHeaderFieldsTooLarge() {
return doMatch(HttpStatus.valueOf(431)); return assertStatusIsEqualTo(HttpStatus.valueOf(431));
} }
/** /**
@ -499,94 +511,94 @@ public class ResponseStatusAssertions {
* @since 4.3 * @since 4.3
*/ */
public ExchangeActions isUnavailableForLegalReasons() { 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). * Assert the response status code is {@code HttpStatus.INTERNAL_SERVER_ERROR} (500).
*/ */
public ExchangeActions isInternalServerError() { 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). * Assert the response status code is {@code HttpStatus.NOT_IMPLEMENTED} (501).
*/ */
public ExchangeActions isNotImplemented() { public ExchangeActions isNotImplemented() {
return doMatch(HttpStatus.NOT_IMPLEMENTED); return assertStatusIsEqualTo(HttpStatus.NOT_IMPLEMENTED);
} }
/** /**
* Assert the response status code is {@code HttpStatus.BAD_GATEWAY} (502). * Assert the response status code is {@code HttpStatus.BAD_GATEWAY} (502).
*/ */
public ExchangeActions isBadGateway() { public ExchangeActions isBadGateway() {
return doMatch(HttpStatus.BAD_GATEWAY); return assertStatusIsEqualTo(HttpStatus.BAD_GATEWAY);
} }
/** /**
* Assert the response status code is {@code HttpStatus.SERVICE_UNAVAILABLE} (503). * Assert the response status code is {@code HttpStatus.SERVICE_UNAVAILABLE} (503).
*/ */
public ExchangeActions isServiceUnavailable() { public ExchangeActions isServiceUnavailable() {
return doMatch(HttpStatus.SERVICE_UNAVAILABLE); return assertStatusIsEqualTo(HttpStatus.SERVICE_UNAVAILABLE);
} }
/** /**
* Assert the response status code is {@code HttpStatus.GATEWAY_TIMEOUT} (504). * Assert the response status code is {@code HttpStatus.GATEWAY_TIMEOUT} (504).
*/ */
public ExchangeActions isGatewayTimeout() { 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). * Assert the response status code is {@code HttpStatus.HTTP_VERSION_NOT_SUPPORTED} (505).
*/ */
public ExchangeActions isHttpVersionNotSupported() { 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). * Assert the response status code is {@code HttpStatus.VARIANT_ALSO_NEGOTIATES} (506).
*/ */
public ExchangeActions isVariantAlsoNegotiates() { 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). * Assert the response status code is {@code HttpStatus.INSUFFICIENT_STORAGE} (507).
*/ */
public ExchangeActions isInsufficientStorage() { public ExchangeActions isInsufficientStorage() {
return doMatch(HttpStatus.INSUFFICIENT_STORAGE); return assertStatusIsEqualTo(HttpStatus.INSUFFICIENT_STORAGE);
} }
/** /**
* Assert the response status code is {@code HttpStatus.LOOP_DETECTED} (508). * Assert the response status code is {@code HttpStatus.LOOP_DETECTED} (508).
*/ */
public ExchangeActions isLoopDetected() { 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). * Assert the response status code is {@code HttpStatus.BANDWIDTH_LIMIT_EXCEEDED} (509).
*/ */
public ExchangeActions isBandwidthLimitExceeded() { public ExchangeActions isBandwidthLimitExceeded() {
return doMatch(HttpStatus.valueOf(509)); return assertStatusIsEqualTo(HttpStatus.valueOf(509));
} }
/** /**
* Assert the response status code is {@code HttpStatus.NOT_EXTENDED} (510). * Assert the response status code is {@code HttpStatus.NOT_EXTENDED} (510).
*/ */
public ExchangeActions isNotExtended() { 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). * Assert the response status code is {@code HttpStatus.NETWORK_AUTHENTICATION_REQUIRED} (511).
*/ */
public ExchangeActions isNetworkAuthenticationRequired() { 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); assertEquals("Status", status, this.httpStatus);
return this.exchangeActions; return this.exchangeActions;
} }

View File

@ -15,6 +15,8 @@
*/ */
package org.springframework.test.web.reactive.server.samples; package org.springframework.test.web.reactive.server.samples;
import java.util.Arrays;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
@ -22,8 +24,11 @@ import org.springframework.http.ResponseEntity;
import org.springframework.test.web.reactive.server.WebTestClient; import org.springframework.test.web.reactive.server.WebTestClient;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import static org.junit.Assert.assertEquals;
/** /**
* Tests with custom headers. * Tests with custom headers.
* *
@ -37,27 +42,45 @@ public class HeaderTests {
@Before @Before
public void setUp() throws Exception { public void setUp() throws Exception {
this.client = WebTestClient.bindToController(new TestController()).build(); this.client = WebTestClient
.bindToController(new TestController())
.webClientSpec().baseUrl("/header")
.build();
} }
@Test @Test
public void customHeader() throws Exception { public void requestResponseHeaderPair() throws Exception {
this.client.get().uri("/header").header("h1", "ping") this.client.get().uri("/request-response-pair").header("h1", "in")
.exchange() .exchange()
.assertStatus().isOk() .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 @RestController
@RequestMapping("header")
static class TestController { static class TestController {
@GetMapping("header") @GetMapping("request-response-pair")
ResponseEntity<Void> handleHeader(@RequestHeader("h1") String myHeader) { ResponseEntity<Void> handleHeader(@RequestHeader("h1") String myHeader) {
String value = myHeader + "-pong"; String value = myHeader + "-out";
return ResponseEntity.ok().header("h1", value).build(); 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; package org.springframework.test.web.reactive.server.samples;
import java.net.URI; import java.net.URI;
import java.util.LinkedHashMap;
import java.util.Map;
import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty; 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 org.springframework.web.bind.annotation.RestController;
import static org.hamcrest.CoreMatchers.endsWith; import static org.hamcrest.CoreMatchers.endsWith;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat; import static org.junit.Assert.assertThat;
import static org.springframework.http.MediaType.TEXT_EVENT_STREAM; import static org.springframework.http.MediaType.TEXT_EVENT_STREAM;
@ -65,7 +68,7 @@ public class ResponseEntityTests {
} }
@Test @Test
public void entityCollection() throws Exception { public void entityList() throws Exception {
this.client.get().uri("/persons") this.client.get().uri("/persons")
.exchange() .exchange()
.assertStatus().isOk() .assertStatus().isOk()
@ -75,6 +78,14 @@ public class ResponseEntityTests {
.contains(new Person("Jane"), new Person("Jason"), new Person("John")); .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 @Test
public void entityStream() throws Exception { public void entityStream() throws Exception {
this.client.get().uri("/persons").accept(TEXT_EVENT_STREAM) this.client.get().uri("/persons").accept(TEXT_EVENT_STREAM)
@ -90,7 +101,7 @@ public class ResponseEntityTests {
} }
@Test @Test
public void saveEntity() throws Exception { public void postEntity() throws Exception {
this.client.post().uri("/persons") this.client.post().uri("/persons")
.exchange(Mono.just(new Person("John")), Person.class) .exchange(Mono.just(new Person("John")), Person.class)
.assertStatus().isCreated() .assertStatus().isCreated()
@ -98,6 +109,14 @@ public class ResponseEntityTests {
.assertBody().isEmpty(); .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 @RestController
@RequestMapping("/persons") @RequestMapping("/persons")
@ -113,6 +132,15 @@ public class ResponseEntityTests {
return Flux.just(new Person("Jane"), new Person("Jason"), new Person("John")); 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") @GetMapping(produces = "text/event-stream")
Flux<Person> getPersonStream() { Flux<Person> getPersonStream() {
return Flux.intervalMillis(100).onBackpressureBuffer(10).map(index -> new Person("N" + index)); return Flux.intervalMillis(100).onBackpressureBuffer(10).map(index -> new Person("N" + index));