Revise queryParam() and header() support in MockRestRequestMatchers
See gh-29953 See gh-29964
This commit is contained in:
@@ -23,7 +23,6 @@ import java.util.Map;
|
||||
import javax.xml.xpath.XPathExpressionException;
|
||||
|
||||
import org.hamcrest.Matcher;
|
||||
import org.hamcrest.Matchers;
|
||||
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.client.ClientHttpRequest;
|
||||
@@ -48,6 +47,7 @@ import static org.springframework.test.util.AssertionErrors.fail;
|
||||
* @author Craig Walls
|
||||
* @author Rossen Stoyanchev
|
||||
* @author Sam Brannen
|
||||
* @author Simon Baslé
|
||||
* @since 3.2
|
||||
*/
|
||||
public abstract class MockRestRequestMatchers {
|
||||
@@ -113,13 +113,49 @@ public abstract class MockRestRequestMatchers {
|
||||
return request -> assertEquals("Unexpected request", uri, request.getURI());
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert request query parameter values with the given Hamcrest matcher,
|
||||
* matching on the entire {@link List} of values.
|
||||
* <p>For example, this can be used to check that the list of query parameter
|
||||
* values has at least one value matching a given Hamcrest matcher (such as
|
||||
* {@link org.hamcrest.Matchers#hasItem(Matcher)}), that every value in the list
|
||||
* matches common criteria (such as {@link org.hamcrest.Matchers#everyItem(Matcher)}),
|
||||
* that each value in the list matches corresponding dedicated criteria
|
||||
* (such as {@link org.hamcrest.Matchers#contains(Matcher[])}, etc.
|
||||
* @param name the name of the query parameter whose value(s) will be asserted
|
||||
* @param matcher the Hamcrest matcher to apply to the entire list of values
|
||||
* for the given query parameter
|
||||
* @since 5.3.26
|
||||
* @see #queryParam(String, Matcher...)
|
||||
* @see #queryParam(String, String...)
|
||||
*/
|
||||
public static RequestMatcher queryParam(String name, Matcher<? super List<String>> matcher) {
|
||||
return request -> {
|
||||
MultiValueMap<String, String> params = getQueryParams(request);
|
||||
List<String> paramValues = params.get(name);
|
||||
if (paramValues == null) {
|
||||
fail("Expected query param <" + name + "> to exist but was null");
|
||||
}
|
||||
assertThat("Query param [" + name + "] values", paramValues, matcher);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert request query parameter values with the given Hamcrest matcher(s).
|
||||
* <p>Note that if the queryParam value list is larger than the number of provided
|
||||
* {@code matchers}, extra values are considered acceptable.
|
||||
* See {@link #queryParam(String, Matcher)} for a variant that takes a
|
||||
* {@code Matcher} over the whole list of values.
|
||||
* <p>If the query parameter value list is larger than the number of provided
|
||||
* {@code matchers}, no matchers will be applied to the extra query parameter
|
||||
* values, effectively ignoring the additional parameter values. If the number
|
||||
* of provided {@code matchers} exceeds the number of query parameter values,
|
||||
* an {@link AssertionError} will be thrown to signal the mismatch.
|
||||
* <p>See {@link #queryParam(String, Matcher)} for a variant which accepts a
|
||||
* {@code Matcher} that applies to the entire list of values as opposed to
|
||||
* applying only to individual values.
|
||||
* @param name the name of the query parameter whose value(s) will be asserted
|
||||
* @param matchers the Hamcrest matchers to apply to individual query parameter
|
||||
* values; the n<sup>th</sup> matcher is applied to the n<sup>th</sup> query
|
||||
* parameter value
|
||||
* @see #queryParam(String, Matcher)
|
||||
* @see #queryParam(String, String...)
|
||||
*/
|
||||
@SafeVarargs
|
||||
public static RequestMatcher queryParam(String name, Matcher<? super String>... matchers) {
|
||||
@@ -134,11 +170,20 @@ public abstract class MockRestRequestMatchers {
|
||||
|
||||
/**
|
||||
* Assert request query parameter values.
|
||||
* <p>Note that if the queryParam value list is larger than {@code expectedValues},
|
||||
* extra values are considered acceptable.
|
||||
* See {@link #queryParam(String, Matcher)} for a variant that takes a
|
||||
* {@code Matcher} over the whole list of values.
|
||||
* <p>If the query parameter value list is larger than the number of
|
||||
* {@code expectedValues}, no assertions will be applied to the extra query
|
||||
* parameter values, effectively ignoring the additional parameter values. If
|
||||
* the number of {@code expectedValues} exceeds the number of query parameter
|
||||
* values, an {@link AssertionError} will be thrown to signal the mismatch.
|
||||
* <p>See {@link #queryParam(String, Matcher)} for a variant which accepts a
|
||||
* Hamcrest {@code Matcher} that applies to the entire list of values as opposed
|
||||
* to asserting only individual values.
|
||||
* @param name the name of the query parameter whose value(s) will be asserted
|
||||
* @param expectedValues the expected values of individual query parameter values;
|
||||
* the n<sup>th</sup> expected value is compared to the n<sup>th</sup> query
|
||||
* parameter value
|
||||
* @see #queryParam(String, Matcher)
|
||||
* @see #queryParam(String, Matcher...)
|
||||
*/
|
||||
public static RequestMatcher queryParam(String name, String... expectedValues) {
|
||||
return request -> {
|
||||
@@ -150,53 +195,51 @@ public abstract class MockRestRequestMatchers {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert request query parameter, matching on the whole {@code List} of values.
|
||||
* <p>This can be used to check that the list has at least one value matching a
|
||||
* criteria ({@link Matchers#hasItem(Matcher)}), or that every value in the list
|
||||
* matches a common criteria ({@link Matchers#everyItem(Matcher)}), or that each
|
||||
* value in the list matches its corresponding dedicated criteria
|
||||
* ({@link Matchers#contains(Matcher[])}, and more.
|
||||
* @param name the name of the query parameter to consider
|
||||
* @param matcher the matcher to apply to the whole list of values for that header
|
||||
* @since 5.3.26
|
||||
*/
|
||||
public static RequestMatcher queryParam(String name, Matcher<? super List<String>> matcher) {
|
||||
return request -> {
|
||||
MultiValueMap<String, String> params = getQueryParams(request);
|
||||
List<String> paramValues = params.get(name);
|
||||
if (paramValues == null) {
|
||||
fail("No queryParam [" + name + "]");
|
||||
}
|
||||
assertThat("Request queryParam values for [" + name + "]", paramValues, matcher);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
private static MultiValueMap<String, String> getQueryParams(ClientHttpRequest request) {
|
||||
return UriComponentsBuilder.fromUri(request.getURI()).build().getQueryParams();
|
||||
}
|
||||
|
||||
private static void assertValueCount(
|
||||
String valueType, String name, MultiValueMap<String, String> map, int count) {
|
||||
|
||||
List<String> values = map.get(name);
|
||||
String message = "Expected " + valueType + " <" + name + ">";
|
||||
if (values == null) {
|
||||
fail(message + " to exist but was null");
|
||||
}
|
||||
if (count > values.size()) {
|
||||
fail(message + " to have at least <" + count + "> values but found " + values);
|
||||
}
|
||||
/**
|
||||
* Assert request header values with the given Hamcrest matcher, matching on
|
||||
* the entire {@link List} of values.
|
||||
* <p>For example, this can be used to check that the list of header values
|
||||
* has at least one value matching a given Hamcrest matcher (such as
|
||||
* {@link org.hamcrest.Matchers#hasItem(Matcher)}), that every value in the list
|
||||
* matches common criteria (such as {@link org.hamcrest.Matchers#everyItem(Matcher)}),
|
||||
* that each value in the list matches corresponding dedicated criteria
|
||||
* (such as {@link org.hamcrest.Matchers#contains(Matcher[])}, etc.
|
||||
* @param name the name of the header whose value(s) will be asserted
|
||||
* @param matcher the Hamcrest matcher to apply to the entire list of values
|
||||
* for the given header
|
||||
* @since 5.3.26
|
||||
* @see #header(String, Matcher...)
|
||||
* @see #header(String, String...)
|
||||
*/
|
||||
public static RequestMatcher header(String name, Matcher<? super List<String>> matcher) {
|
||||
return request -> {
|
||||
List<String> headerValues = request.getHeaders().get(name);
|
||||
if (headerValues == null) {
|
||||
fail("Expected header <" + name + "> to exist but was null");
|
||||
}
|
||||
assertThat("Request header [" + name + "] values", headerValues, matcher);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert request header values with the given Hamcrest matcher(s).
|
||||
* <p>Note that if the header's value list is larger than the number of provided
|
||||
* {@code matchers}, extra values are considered acceptable.
|
||||
* See {@link #header(String, Matcher)} for a variant that takes a {@code Matcher}
|
||||
* over the whole list of values.
|
||||
* <p>If the header value list is larger than the number of provided
|
||||
* {@code matchers}, no matchers will be applied to the extra header values,
|
||||
* effectively ignoring the additional header values. If the number of
|
||||
* provided {@code matchers} exceeds the number of header values, an
|
||||
* {@link AssertionError} will be thrown to signal the mismatch.
|
||||
* <p>See {@link #header(String, Matcher)} for a variant which accepts a
|
||||
* Hamcrest {@code Matcher} that applies to the entire list of values as
|
||||
* opposed to applying only to individual values.
|
||||
* @param name the name of the header whose value(s) will be asserted
|
||||
* @param matchers the Hamcrest matchers to apply to individual header values;
|
||||
* the n<sup>th</sup> matcher is applied to the n<sup>th</sup> header value
|
||||
* @see #header(String, Matcher)
|
||||
* @see #header(String, String...)
|
||||
*/
|
||||
@SafeVarargs
|
||||
public static RequestMatcher header(String name, Matcher<? super String>... matchers) {
|
||||
@@ -212,11 +255,19 @@ public abstract class MockRestRequestMatchers {
|
||||
|
||||
/**
|
||||
* Assert request header values.
|
||||
* <p>Note that if the header's value list is larger than {@code expectedValues},
|
||||
* extra values are considered acceptable.
|
||||
* See {@link #header(String, Matcher)} for a variant that takes a {@code Matcher}
|
||||
* over the whole list of values.
|
||||
* <p>If the header value list is larger than the number of {@code expectedValues},
|
||||
* no matchers will be applied to the extra header values, effectively ignoring the
|
||||
* additional header values. If the number of {@code expectedValues} exceeds the
|
||||
* number of header values, an {@link AssertionError} will be thrown to signal the
|
||||
* mismatch.
|
||||
* <p>See {@link #header(String, Matcher)} for a variant which accepts a
|
||||
* Hamcrest {@code Matcher} that applies to the entire list of values as
|
||||
* opposed to applying only to individual values.
|
||||
* @param name the name of the header whose value(s) will be asserted
|
||||
* @param expectedValues the expected values of individual header values; the
|
||||
* n<sup>th</sup> expected value is compared to the n<sup>th</sup> header value
|
||||
* @see #header(String, Matcher)
|
||||
* @see #header(String, Matcher...)
|
||||
*/
|
||||
public static RequestMatcher header(String name, String... expectedValues) {
|
||||
return request -> {
|
||||
@@ -229,27 +280,6 @@ public abstract class MockRestRequestMatchers {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert request header, matching on the whole {@code List} of values.
|
||||
* <p>This can be used to check that the list has at least one value matching a
|
||||
* criteria ({@link Matchers#hasItem(Matcher)}), or that every value in the list
|
||||
* matches a common criteria ({@link Matchers#everyItem(Matcher)}), or that each
|
||||
* value in the list matches its corresponding dedicated criteria
|
||||
* ({@link Matchers#contains(Matcher[])}, and more.
|
||||
* @param name the name of the request header to consider
|
||||
* @param matcher the matcher to apply to the whole list of values for that header
|
||||
* @since 5.3.26
|
||||
*/
|
||||
public static RequestMatcher header(String name, Matcher<? super List<String>> matcher) {
|
||||
return request -> {
|
||||
List<String> headerValues = request.getHeaders().get(name);
|
||||
if (headerValues == null) {
|
||||
fail("No header values for header [" + name + "]");
|
||||
}
|
||||
assertThat("Request header values for [" + name + "]", headerValues, matcher);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert that the given request header does not exist.
|
||||
* @since 5.2
|
||||
@@ -323,4 +353,18 @@ public abstract class MockRestRequestMatchers {
|
||||
return new XpathRequestMatchers(expression, namespaces, args);
|
||||
}
|
||||
|
||||
|
||||
private static void assertValueCount(
|
||||
String valueType, String name, MultiValueMap<String, String> map, int count) {
|
||||
|
||||
List<String> values = map.get(name);
|
||||
String message = "Expected " + valueType + " <" + name + ">";
|
||||
if (values == null) {
|
||||
fail(message + " to exist but was null");
|
||||
}
|
||||
if (count > values.size()) {
|
||||
fail(message + " to have at least <" + count + "> values but found " + values);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user