Add Consumer methods to WebTestClient assertion classes
Issue: SPR-16574
This commit is contained in:
@@ -20,19 +20,15 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.jayway.jsonpath.JsonPath;
|
||||
import org.hamcrest.CoreMatchers;
|
||||
import org.hamcrest.Matcher;
|
||||
import org.hamcrest.MatcherAssert;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.core.IsInstanceOf.instanceOf;
|
||||
import static org.springframework.test.util.AssertionErrors.assertEquals;
|
||||
import static org.springframework.test.util.AssertionErrors.assertTrue;
|
||||
import static org.springframework.test.util.AssertionErrors.fail;
|
||||
|
||||
/**
|
||||
* A helper class for applying assertions via JSON path expressions.
|
||||
*
|
||||
@@ -74,7 +70,7 @@ public class JsonPathExpectationsHelper {
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> void assertValue(String content, Matcher<T> matcher) {
|
||||
T value = (T) evaluateJsonPath(content);
|
||||
assertThat("JSON path \"" + this.expression + "\"", value, matcher);
|
||||
MatcherAssert.assertThat("JSON path \"" + this.expression + "\"", value, matcher);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -89,7 +85,7 @@ public class JsonPathExpectationsHelper {
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> void assertValue(String content, Matcher<T> matcher, Class<T> targetType) {
|
||||
T value = (T) evaluateJsonPath(content, targetType);
|
||||
assertThat("JSON path \"" + this.expression + "\"", value, matcher);
|
||||
MatcherAssert.assertThat("JSON path \"" + this.expression + "\"", value, matcher);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -104,10 +100,11 @@ public class JsonPathExpectationsHelper {
|
||||
@SuppressWarnings("rawtypes")
|
||||
List actualValueList = (List) actualValue;
|
||||
if (actualValueList.isEmpty()) {
|
||||
fail("No matching value at JSON path \"" + this.expression + "\"");
|
||||
AssertionErrors.fail("No matching value at JSON path \"" + this.expression + "\"");
|
||||
}
|
||||
if (actualValueList.size() != 1) {
|
||||
fail("Got a list of values " + actualValue + " instead of the expected single value " + expectedValue);
|
||||
AssertionErrors.fail("Got a list of values " + actualValue +
|
||||
" instead of the expected single value " + expectedValue);
|
||||
}
|
||||
actualValue = actualValueList.get(0);
|
||||
}
|
||||
@@ -116,7 +113,7 @@ public class JsonPathExpectationsHelper {
|
||||
actualValue = evaluateJsonPath(content, expectedValue.getClass());
|
||||
}
|
||||
}
|
||||
assertEquals("JSON path \"" + this.expression + "\"", expectedValue, actualValue);
|
||||
AssertionErrors.assertEquals("JSON path \"" + this.expression + "\"", expectedValue, actualValue);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -127,7 +124,7 @@ public class JsonPathExpectationsHelper {
|
||||
*/
|
||||
public void assertValueIsString(String content) {
|
||||
Object value = assertExistsAndReturn(content);
|
||||
assertThat(failureReason("a string", value), value, instanceOf(String.class));
|
||||
MatcherAssert.assertThat(failureReason("a string", value), value, CoreMatchers.instanceOf(String.class));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -138,7 +135,7 @@ public class JsonPathExpectationsHelper {
|
||||
*/
|
||||
public void assertValueIsBoolean(String content) {
|
||||
Object value = assertExistsAndReturn(content);
|
||||
assertThat(failureReason("a boolean", value), value, instanceOf(Boolean.class));
|
||||
MatcherAssert.assertThat(failureReason("a boolean", value), value, CoreMatchers.instanceOf(Boolean.class));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -149,7 +146,7 @@ public class JsonPathExpectationsHelper {
|
||||
*/
|
||||
public void assertValueIsNumber(String content) {
|
||||
Object value = assertExistsAndReturn(content);
|
||||
assertThat(failureReason("a number", value), value, instanceOf(Number.class));
|
||||
MatcherAssert.assertThat(failureReason("a number", value), value, CoreMatchers.instanceOf(Number.class));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -159,7 +156,7 @@ public class JsonPathExpectationsHelper {
|
||||
*/
|
||||
public void assertValueIsArray(String content) {
|
||||
Object value = assertExistsAndReturn(content);
|
||||
assertThat(failureReason("an array", value), value, instanceOf(List.class));
|
||||
MatcherAssert.assertThat(failureReason("an array", value), value, CoreMatchers.instanceOf(List.class));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -170,7 +167,7 @@ public class JsonPathExpectationsHelper {
|
||||
*/
|
||||
public void assertValueIsMap(String content) {
|
||||
Object value = assertExistsAndReturn(content);
|
||||
assertThat(failureReason("a map", value), value, instanceOf(Map.class));
|
||||
MatcherAssert.assertThat(failureReason("a map", value), value, CoreMatchers.instanceOf(Map.class));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -204,10 +201,10 @@ public class JsonPathExpectationsHelper {
|
||||
}
|
||||
String reason = failureReason("no value", value);
|
||||
if (pathIsIndefinite() && value instanceof List) {
|
||||
assertTrue(reason, ((List<?>) value).isEmpty());
|
||||
AssertionErrors.assertTrue(reason, ((List<?>) value).isEmpty());
|
||||
}
|
||||
else {
|
||||
assertTrue(reason, (value == null));
|
||||
AssertionErrors.assertTrue(reason, (value == null));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -220,7 +217,7 @@ public class JsonPathExpectationsHelper {
|
||||
*/
|
||||
public void assertValueIsEmpty(String content) {
|
||||
Object value = evaluateJsonPath(content);
|
||||
assertTrue(failureReason("an empty value", value), ObjectUtils.isEmpty(value));
|
||||
AssertionErrors.assertTrue(failureReason("an empty value", value), ObjectUtils.isEmpty(value));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -232,7 +229,7 @@ public class JsonPathExpectationsHelper {
|
||||
*/
|
||||
public void assertValueIsNotEmpty(String content) {
|
||||
Object value = evaluateJsonPath(content);
|
||||
assertTrue(failureReason("a non-empty value", value), !ObjectUtils.isEmpty(value));
|
||||
AssertionErrors.assertTrue(failureReason("a non-empty value", value), !ObjectUtils.isEmpty(value));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -247,7 +244,8 @@ public class JsonPathExpectationsHelper {
|
||||
public void hasJsonPath(String content) {
|
||||
Object value = evaluateJsonPath(content);
|
||||
if (pathIsIndefinite() && value instanceof List) {
|
||||
assertTrue("No values for JSON path \"" + this.expression + "\"", !((List<?>) value).isEmpty());
|
||||
String message = "No values for JSON path \"" + this.expression + "\"";
|
||||
AssertionErrors.assertTrue(message, !((List<?>) value).isEmpty());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -270,10 +268,10 @@ public class JsonPathExpectationsHelper {
|
||||
return;
|
||||
}
|
||||
if (pathIsIndefinite() && value instanceof List) {
|
||||
assertTrue(failureReason("no values", value), ((List<?>) value).isEmpty());
|
||||
AssertionErrors.assertTrue(failureReason("no values", value), ((List<?>) value).isEmpty());
|
||||
}
|
||||
else {
|
||||
fail(failureReason("no value", value));
|
||||
AssertionErrors.fail(failureReason("no value", value));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -282,18 +280,31 @@ public class JsonPathExpectationsHelper {
|
||||
ObjectUtils.nullSafeToString(StringUtils.quoteIfString(value)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluate the JSON path and return the resulting value.
|
||||
* @param content the content to evaluate against
|
||||
* @return the result of the evaluation
|
||||
* @throws AssertionError if the evaluation fails
|
||||
*/
|
||||
@Nullable
|
||||
private Object evaluateJsonPath(String content) {
|
||||
public Object evaluateJsonPath(String content) {
|
||||
try {
|
||||
return this.jsonPath.read(content);
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
String message = "No value at JSON path \"" + this.expression + "\"";
|
||||
throw new AssertionError(message, ex);
|
||||
throw new AssertionError("No value at JSON path \"" + this.expression + "\"", ex);
|
||||
}
|
||||
}
|
||||
|
||||
private Object evaluateJsonPath(String content, Class<?> targetType) {
|
||||
/**
|
||||
* Variant of {@link #evaluateJsonPath(String)} with a target type.
|
||||
* This can be useful for matching numbers reliably for example coercing an
|
||||
* integer into a double.
|
||||
* @param content the content to evaluate against
|
||||
* @return the result of the evaluation
|
||||
* @throws AssertionError if the evaluation fails
|
||||
*/
|
||||
public Object evaluateJsonPath(String content, Class<?> targetType) {
|
||||
try {
|
||||
return JsonPath.parse(content).read(this.expression, targetType);
|
||||
}
|
||||
@@ -307,9 +318,9 @@ public class JsonPathExpectationsHelper {
|
||||
private Object assertExistsAndReturn(String content) {
|
||||
Object value = evaluateJsonPath(content);
|
||||
String reason = "No value at JSON path \"" + this.expression + "\"";
|
||||
assertTrue(reason, value != null);
|
||||
AssertionErrors.assertTrue(reason, value != null);
|
||||
if (pathIsIndefinite() && value instanceof List) {
|
||||
assertTrue(reason, !((List<?>) value).isEmpty());
|
||||
AssertionErrors.assertTrue(reason, !((List<?>) value).isEmpty());
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ import javax.xml.xpath.XPathExpressionException;
|
||||
import javax.xml.xpath.XPathFactory;
|
||||
|
||||
import org.hamcrest.Matcher;
|
||||
import org.hamcrest.MatcherAssert;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
@@ -39,9 +40,6 @@ import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.util.xml.SimpleNamespaceContext;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.springframework.test.util.AssertionErrors.assertEquals;
|
||||
import static org.springframework.test.util.AssertionErrors.assertTrue;
|
||||
|
||||
/**
|
||||
* A helper class for applying assertions via XPath expressions.
|
||||
@@ -74,9 +72,8 @@ public class XpathExpectationsHelper {
|
||||
this.hasNamespaces = !CollectionUtils.isEmpty(namespaces);
|
||||
}
|
||||
|
||||
|
||||
private XPathExpression compileXpathExpression(String expression, @Nullable Map<String, String> namespaces)
|
||||
throws XPathExpressionException {
|
||||
private static XPathExpression compileXpathExpression(String expression,
|
||||
@Nullable Map<String, String> namespaces) throws XPathExpressionException {
|
||||
|
||||
SimpleNamespaceContext namespaceContext = new SimpleNamespaceContext();
|
||||
namespaceContext.setBindings(namespaces != null ? namespaces : Collections.emptyMap());
|
||||
@@ -85,6 +82,7 @@ public class XpathExpectationsHelper {
|
||||
return xpath.compile(expression);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the compiled XPath expression.
|
||||
*/
|
||||
@@ -92,6 +90,7 @@ public class XpathExpectationsHelper {
|
||||
return this.xpathExpression;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parse the content, evaluate the XPath expression as a {@link Node},
|
||||
* and assert it with the given {@code Matcher<Node>}.
|
||||
@@ -99,9 +98,113 @@ public class XpathExpectationsHelper {
|
||||
public void assertNode(byte[] content, @Nullable String encoding, final Matcher<? super Node> matcher)
|
||||
throws Exception {
|
||||
|
||||
Node node = evaluateXpath(content, encoding, Node.class);
|
||||
MatcherAssert.assertThat("XPath " + this.expression, node, matcher);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the XPath expression and assert the resulting content exists.
|
||||
* @throws Exception if content parsing or expression evaluation fails
|
||||
*/
|
||||
public void exists(byte[] content, @Nullable String encoding) throws Exception {
|
||||
Node node = evaluateXpath(content, encoding, Node.class);
|
||||
AssertionErrors.assertTrue("XPath " + this.expression + " does not exist", node != null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the XPath expression and assert the resulting content does not exist.
|
||||
* @throws Exception if content parsing or expression evaluation fails
|
||||
*/
|
||||
public void doesNotExist(byte[] content, @Nullable String encoding) throws Exception {
|
||||
Node node = evaluateXpath(content, encoding, Node.class);
|
||||
AssertionErrors.assertTrue("XPath " + this.expression + " exists", node == null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the XPath expression and assert the resulting content with the
|
||||
* given Hamcrest matcher.
|
||||
* @throws Exception if content parsing or expression evaluation fails
|
||||
*/
|
||||
public void assertNodeCount(byte[] content, @Nullable String encoding, Matcher<Integer> matcher)
|
||||
throws Exception {
|
||||
|
||||
NodeList nodeList = evaluateXpath(content, encoding, NodeList.class);
|
||||
String reason = "nodeCount for XPath " + this.expression;
|
||||
MatcherAssert.assertThat(reason, nodeList != null ? nodeList.getLength() : 0, matcher);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the XPath expression and assert the resulting content as an integer.
|
||||
* @throws Exception if content parsing or expression evaluation fails
|
||||
*/
|
||||
public void assertNodeCount(byte[] content, @Nullable String encoding, int expectedCount) throws Exception {
|
||||
NodeList nodeList = evaluateXpath(content, encoding, NodeList.class);
|
||||
AssertionErrors.assertEquals("nodeCount for XPath " + this.expression, expectedCount,
|
||||
(nodeList != null ? nodeList.getLength() : 0));
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the XPath expression and assert the resulting content with the
|
||||
* given Hamcrest matcher.
|
||||
* @throws Exception if content parsing or expression evaluation fails
|
||||
*/
|
||||
public void assertString(byte[] content, @Nullable String encoding, Matcher<? super String> matcher)
|
||||
throws Exception {
|
||||
|
||||
String actual = evaluateXpath(content, encoding, String.class);
|
||||
MatcherAssert.assertThat("XPath " + this.expression, actual, matcher);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the XPath expression and assert the resulting content as a String.
|
||||
* @throws Exception if content parsing or expression evaluation fails
|
||||
*/
|
||||
public void assertString(byte[] content, @Nullable String encoding, String expectedValue) throws Exception {
|
||||
String actual = evaluateXpath(content, encoding, String.class);
|
||||
AssertionErrors.assertEquals("XPath " + this.expression, expectedValue, actual);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the XPath expression and assert the resulting content with the
|
||||
* given Hamcrest matcher.
|
||||
* @throws Exception if content parsing or expression evaluation fails
|
||||
*/
|
||||
public void assertNumber(byte[] content, @Nullable String encoding, Matcher<? super Double> matcher) throws Exception {
|
||||
Double actual = evaluateXpath(content, encoding, Double.class);
|
||||
MatcherAssert.assertThat("XPath " + this.expression, actual, matcher);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the XPath expression and assert the resulting content as a Double.
|
||||
* @throws Exception if content parsing or expression evaluation fails
|
||||
*/
|
||||
public void assertNumber(byte[] content, @Nullable String encoding, Double expectedValue) throws Exception {
|
||||
Double actual = evaluateXpath(content, encoding, Double.class);
|
||||
AssertionErrors.assertEquals("XPath " + this.expression, expectedValue, actual);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the XPath expression and assert the resulting content as a Boolean.
|
||||
* @throws Exception if content parsing or expression evaluation fails
|
||||
*/
|
||||
public void assertBoolean(byte[] content, @Nullable String encoding, boolean expectedValue) throws Exception {
|
||||
String actual = evaluateXpath(content, encoding, String.class);
|
||||
AssertionErrors.assertEquals("XPath " + this.expression, expectedValue, Boolean.parseBoolean(actual));
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluate the XPath and return the resulting value.
|
||||
* @param content the content to evaluate against
|
||||
* @param encoding the encoding to use (optionally)
|
||||
* @param targetClass the target class, one of Number, String, Boolean,
|
||||
* org.w3c.Node, or NodeList
|
||||
* @throws Exception if content parsing or expression evaluation fails
|
||||
* @since 5.1
|
||||
*/
|
||||
@Nullable
|
||||
public <T> T evaluateXpath(byte[] content, @Nullable String encoding, Class<T> targetClass) throws Exception {
|
||||
Document document = parseXmlByteArray(content, encoding);
|
||||
Node node = evaluateXpath(document, XPathConstants.NODE, Node.class);
|
||||
assertThat("XPath " + this.expression, node, matcher);
|
||||
return evaluateXpath(document, toQName(targetClass), targetClass);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -133,99 +236,28 @@ public class XpathExpectationsHelper {
|
||||
return (T) getXpathExpression().evaluate(document, evaluationType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the XPath expression and assert the resulting content exists.
|
||||
* @throws Exception if content parsing or expression evaluation fails
|
||||
*/
|
||||
public void exists(byte[] content, @Nullable String encoding) throws Exception {
|
||||
Document document = parseXmlByteArray(content, encoding);
|
||||
Node node = evaluateXpath(document, XPathConstants.NODE, Node.class);
|
||||
assertTrue("XPath " + this.expression + " does not exist", node != null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the XPath expression and assert the resulting content does not exist.
|
||||
* @throws Exception if content parsing or expression evaluation fails
|
||||
*/
|
||||
public void doesNotExist(byte[] content, @Nullable String encoding) throws Exception {
|
||||
Document document = parseXmlByteArray(content, encoding);
|
||||
Node node = evaluateXpath(document, XPathConstants.NODE, Node.class);
|
||||
assertTrue("XPath " + this.expression + " exists", node == null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the XPath expression and assert the resulting content with the
|
||||
* given Hamcrest matcher.
|
||||
* @throws Exception if content parsing or expression evaluation fails
|
||||
*/
|
||||
public void assertNodeCount(byte[] content, @Nullable String encoding, Matcher<Integer> matcher) throws Exception {
|
||||
Document document = parseXmlByteArray(content, encoding);
|
||||
NodeList nodeList = evaluateXpath(document, XPathConstants.NODESET, NodeList.class);
|
||||
assertThat("nodeCount for XPath " + this.expression,
|
||||
(nodeList != null ? nodeList.getLength() : 0), matcher);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the XPath expression and assert the resulting content as an integer.
|
||||
* @throws Exception if content parsing or expression evaluation fails
|
||||
*/
|
||||
public void assertNodeCount(byte[] content, @Nullable String encoding, int expectedCount) throws Exception {
|
||||
Document document = parseXmlByteArray(content, encoding);
|
||||
NodeList nodeList = evaluateXpath(document, XPathConstants.NODESET, NodeList.class);
|
||||
assertEquals("nodeCount for XPath " + this.expression, expectedCount,
|
||||
(nodeList != null ? nodeList.getLength() : 0));
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the XPath expression and assert the resulting content with the
|
||||
* given Hamcrest matcher.
|
||||
* @throws Exception if content parsing or expression evaluation fails
|
||||
*/
|
||||
public void assertString(byte[] content, @Nullable String encoding, Matcher<? super String> matcher) throws Exception {
|
||||
Document document = parseXmlByteArray(content, encoding);
|
||||
String result = evaluateXpath(document, XPathConstants.STRING, String.class);
|
||||
assertThat("XPath " + this.expression, result, matcher);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the XPath expression and assert the resulting content as a String.
|
||||
* @throws Exception if content parsing or expression evaluation fails
|
||||
*/
|
||||
public void assertString(byte[] content, @Nullable String encoding, String expectedValue) throws Exception {
|
||||
Document document = parseXmlByteArray(content, encoding);
|
||||
String actual = evaluateXpath(document, XPathConstants.STRING, String.class);
|
||||
assertEquals("XPath " + this.expression, expectedValue, actual);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the XPath expression and assert the resulting content with the
|
||||
* given Hamcrest matcher.
|
||||
* @throws Exception if content parsing or expression evaluation fails
|
||||
*/
|
||||
public void assertNumber(byte[] content, @Nullable String encoding, Matcher<? super Double> matcher) throws Exception {
|
||||
Document document = parseXmlByteArray(content, encoding);
|
||||
Double result = evaluateXpath(document, XPathConstants.NUMBER, Double.class);
|
||||
assertThat("XPath " + this.expression, result, matcher);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the XPath expression and assert the resulting content as a Double.
|
||||
* @throws Exception if content parsing or expression evaluation fails
|
||||
*/
|
||||
public void assertNumber(byte[] content, @Nullable String encoding, Double expectedValue) throws Exception {
|
||||
Document document = parseXmlByteArray(content, encoding);
|
||||
Double actual = evaluateXpath(document, XPathConstants.NUMBER, Double.class);
|
||||
assertEquals("XPath " + this.expression, expectedValue, actual);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the XPath expression and assert the resulting content as a Boolean.
|
||||
* @throws Exception if content parsing or expression evaluation fails
|
||||
*/
|
||||
public void assertBoolean(byte[] content, @Nullable String encoding, boolean expectedValue) throws Exception {
|
||||
Document document = parseXmlByteArray(content, encoding);
|
||||
String actual = evaluateXpath(document, XPathConstants.STRING, String.class);
|
||||
assertEquals("XPath " + this.expression, expectedValue, Boolean.parseBoolean(actual));
|
||||
private <T> QName toQName(Class<T> expectedClass) {
|
||||
QName evaluationType;
|
||||
if (Number.class.isAssignableFrom(expectedClass)) {
|
||||
evaluationType = XPathConstants.NUMBER;
|
||||
}
|
||||
else if (CharSequence.class.isAssignableFrom(expectedClass)) {
|
||||
evaluationType = XPathConstants.STRING;
|
||||
}
|
||||
else if (Boolean.class.isAssignableFrom(expectedClass)) {
|
||||
evaluationType = XPathConstants.BOOLEAN;
|
||||
}
|
||||
else if (Node.class.isAssignableFrom(expectedClass)) {
|
||||
evaluationType = XPathConstants.NODE;
|
||||
}
|
||||
else if (NodeList.class.isAssignableFrom(expectedClass)) {
|
||||
evaluationType = XPathConstants.NODESET;
|
||||
}
|
||||
else {
|
||||
throw new IllegalArgumentException("Unexpected target class " + expectedClass + ". " +
|
||||
"Supported: numbers, strings, boolean, and org.w3c.Node and NodeList");
|
||||
}
|
||||
return evaluationType;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -402,6 +402,12 @@ class DefaultWebTestClient implements WebTestClient {
|
||||
return self();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends S> T value(Consumer<B> consumer) {
|
||||
this.result.assertWithDiagnostics(() -> consumer.accept(this.result.getResponseBody()));
|
||||
return self();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends S> T consumeWith(Consumer<EntityExchangeResult<B>> consumer) {
|
||||
this.result.assertWithDiagnostics(() -> consumer.accept(this.result));
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package org.springframework.test.web.reactive.server;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.hamcrest.Matcher;
|
||||
import org.hamcrest.MatcherAssert;
|
||||
@@ -81,6 +82,18 @@ public class HeaderAssertions {
|
||||
return this.responseSpec;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert the primary value of the response header with a {@link Matcher}.
|
||||
* @param name the header name
|
||||
* @param consumer the matcher to sue
|
||||
* @since 5.1
|
||||
*/
|
||||
public WebTestClient.ResponseSpec value(String name, Consumer<String> consumer) {
|
||||
String value = getRequiredValue(name);
|
||||
this.exchangeResult.assertWithDiagnostics(() -> consumer.accept(value));
|
||||
return this.responseSpec;
|
||||
}
|
||||
|
||||
private String getRequiredValue(String name) {
|
||||
String value = getHeaders().getFirst(name);
|
||||
if (value == null) {
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package org.springframework.test.web.reactive.server;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.hamcrest.Matcher;
|
||||
|
||||
import org.springframework.test.util.JsonPathExpectationsHelper;
|
||||
@@ -152,4 +154,26 @@ public class JsonPathAssertions {
|
||||
return this.bodySpec;
|
||||
}
|
||||
|
||||
/**
|
||||
* Consume the result of the JSONPath evaluation.
|
||||
* @since 5.1
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> WebTestClient.BodyContentSpec value(Consumer<T> consumer) {
|
||||
Object value = this.pathHelper.evaluateJsonPath(this.content);
|
||||
consumer.accept((T) value);
|
||||
return this.bodySpec;
|
||||
}
|
||||
|
||||
/**
|
||||
* Consume the result of the JSONPath evaluation and provide a target class.
|
||||
* @since 5.1
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> WebTestClient.BodyContentSpec value(Consumer<T> consumer, Class<T> targetType) {
|
||||
Object value = this.pathHelper.evaluateJsonPath(this.content, targetType);
|
||||
consumer.accept((T) value);
|
||||
return this.bodySpec;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package org.springframework.test.web.reactive.server;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.hamcrest.Matcher;
|
||||
import org.hamcrest.MatcherAssert;
|
||||
|
||||
@@ -208,6 +210,17 @@ public class StatusAssertions {
|
||||
return this.responseSpec;
|
||||
}
|
||||
|
||||
/**
|
||||
* Match the response status value with a Hamcrest matcher.
|
||||
* @param consumer the matcher to use
|
||||
* @since 5.1
|
||||
*/
|
||||
public WebTestClient.ResponseSpec value(Consumer<Integer> consumer) {
|
||||
int value = this.exchangeResult.getStatus().value();
|
||||
this.exchangeResult.assertWithDiagnostics(() -> consumer.accept(value));
|
||||
return this.responseSpec;
|
||||
}
|
||||
|
||||
|
||||
private WebTestClient.ResponseSpec assertStatusAndReturn(HttpStatus expected) {
|
||||
HttpStatus actual = this.exchangeResult.getStatus();
|
||||
|
||||
@@ -772,6 +772,12 @@ public interface WebTestClient {
|
||||
*/
|
||||
<T extends S, R> T value(Function<B, R> bodyMapper, Matcher<R> matcher);
|
||||
|
||||
/**
|
||||
* Assert the extracted body with a {@link Matcher}.
|
||||
* @since 5.1
|
||||
*/
|
||||
<T extends S> T value(Consumer<B> consumer);
|
||||
|
||||
/**
|
||||
* Assert the exchange result with the given {@link Consumer}.
|
||||
*/
|
||||
|
||||
@@ -19,6 +19,7 @@ package org.springframework.test.web.reactive.server;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Consumer;
|
||||
import javax.xml.xpath.XPathExpressionException;
|
||||
|
||||
import org.hamcrest.Matcher;
|
||||
@@ -107,6 +108,7 @@ public class XpathAssertions {
|
||||
|
||||
/**
|
||||
* Delegates to {@link XpathExpectationsHelper#assertString(byte[], String, Matcher)}.
|
||||
* @since 5.1
|
||||
*/
|
||||
public WebTestClient.BodyContentSpec string(Matcher<? super String> matcher){
|
||||
return assertWith(() -> this.xpathHelper.assertString(getContent(), getCharset(), matcher));
|
||||
@@ -114,6 +116,7 @@ public class XpathAssertions {
|
||||
|
||||
/**
|
||||
* Delegates to {@link XpathExpectationsHelper#assertNumber(byte[], String, Matcher)}.
|
||||
* @since 5.1
|
||||
*/
|
||||
public WebTestClient.BodyContentSpec number(Matcher<? super Double> matcher){
|
||||
return assertWith(() -> this.xpathHelper.assertNumber(getContent(), getCharset(), matcher));
|
||||
@@ -121,11 +124,45 @@ public class XpathAssertions {
|
||||
|
||||
/**
|
||||
* Delegates to {@link XpathExpectationsHelper#assertNodeCount(byte[], String, Matcher)}.
|
||||
* @since 5.1
|
||||
*/
|
||||
public WebTestClient.BodyContentSpec nodeCount(Matcher<Integer> matcher){
|
||||
return assertWith(() -> this.xpathHelper.assertNodeCount(getContent(), getCharset(), matcher));
|
||||
}
|
||||
|
||||
/**
|
||||
* Consume the result of the XPath evaluation as a String.
|
||||
* @since 5.1
|
||||
*/
|
||||
public WebTestClient.BodyContentSpec string(Consumer<String> consumer){
|
||||
return assertWith(() -> {
|
||||
String value = this.xpathHelper.evaluateXpath(getContent(), getCharset(), String.class);
|
||||
consumer.accept(value);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Consume the result of the XPath evaluation as a Double.
|
||||
* @since 5.1
|
||||
*/
|
||||
public WebTestClient.BodyContentSpec number(Consumer<Double> consumer){
|
||||
return assertWith(() -> {
|
||||
Double value = this.xpathHelper.evaluateXpath(getContent(), getCharset(), Double.class);
|
||||
consumer.accept(value);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Consume the count of nodes as result of the XPath evaluation.
|
||||
* @since 5.1
|
||||
*/
|
||||
public WebTestClient.BodyContentSpec nodeCount(Consumer<Integer> consumer){
|
||||
return assertWith(() -> {
|
||||
Integer value = this.xpathHelper.evaluateXpath(getContent(), getCharset(), Integer.class);
|
||||
consumer.accept(value);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private WebTestClient.BodyContentSpec assertWith(CheckedExceptionTask task) {
|
||||
try {
|
||||
|
||||
@@ -22,6 +22,7 @@ import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.hamcrest.MatcherAssert;
|
||||
import org.junit.Test;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.test.StepVerifier;
|
||||
@@ -98,6 +99,18 @@ public class ResponseEntityTests {
|
||||
.expectBodyList(Person.class).isEqualTo(expected);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void entityListWithConsumer() {
|
||||
|
||||
this.client.get()
|
||||
.exchange()
|
||||
.expectStatus().isOk()
|
||||
.expectHeader().contentType(MediaType.APPLICATION_JSON_UTF8)
|
||||
.expectBodyList(Person.class).value(people -> {
|
||||
MatcherAssert.assertThat(people, hasItem(new Person("Jason")));
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void entityMap() {
|
||||
|
||||
|
||||
Reference in New Issue
Block a user