From ba826f1026b337ce7739d45f7e12af4b61c8cfea Mon Sep 17 00:00:00 2001 From: schjan79 Date: Wed, 7 Dec 2016 23:56:30 +0100 Subject: [PATCH] MockRestRequestMatchers can match query params Issue: SPR-14995 --- .../client/match/MockRestRequestMatchers.java | 77 +++++++++++++++- .../match/MockRestRequestMatchersTests.java | 87 +++++++++++++++++-- 2 files changed, 155 insertions(+), 9 deletions(-) diff --git a/spring-test/src/main/java/org/springframework/test/web/client/match/MockRestRequestMatchers.java b/spring-test/src/main/java/org/springframework/test/web/client/match/MockRestRequestMatchers.java index d9d78bb9d9c..d7835118e96 100644 --- a/spring-test/src/main/java/org/springframework/test/web/client/match/MockRestRequestMatchers.java +++ b/spring-test/src/main/java/org/springframework/test/web/client/match/MockRestRequestMatchers.java @@ -18,6 +18,7 @@ package org.springframework.test.web.client.match; import java.io.IOException; import java.net.URI; +import java.nio.charset.Charset; import java.util.List; import java.util.Map; import javax.xml.xpath.XPathExpressionException; @@ -31,7 +32,11 @@ import org.springframework.test.util.AssertionErrors; import org.springframework.test.web.client.MockRestServiceServer; import org.springframework.test.web.client.RequestMatcher; import org.springframework.util.Assert; +import org.springframework.util.MultiValueMap; +import org.springframework.web.util.UriComponentsBuilder; +import org.springframework.web.util.UriUtils; +import static java.nio.charset.StandardCharsets.UTF_8; import static org.hamcrest.MatcherAssert.*; import static org.springframework.test.util.AssertionErrors.*; @@ -153,9 +158,75 @@ public abstract class MockRestRequestMatchers { } private static void assertHeaderValueCount(final String name, HttpHeaders headers, int expectedCount) { - List actualValues = headers.get(name); - AssertionErrors.assertTrue("Expected header <" + name + ">", actualValues != null); - AssertionErrors.assertTrue("Expected header <" + name + "> to have at least <" + expectedCount + + assertMultiValueMapCount("header", name, headers, expectedCount); + } + + + /** + * Assert request query parameter values with the given Hamcrest matcher. + */ + @SafeVarargs + public static RequestMatcher queryParameter(final String name, final Matcher... matchers) { + return queryParameter(name, UTF_8, matchers); + } + + /** + * Assert request query parameter values with the given Hamcrest matcher. + */ + @SafeVarargs + public static RequestMatcher queryParameter(final String name, final Charset charset, + final Matcher... matchers) { + return new RequestMatcher() { + @Override + public void match(ClientHttpRequest request) { + MultiValueMap queryParameters = getQueryParameters(request.getURI().toString(), charset); + assertQueryParameterValueCount(name, queryParameters, matchers.length); + for (int i = 0 ; i < matchers.length; i++) { + assertThat("Request query parameter", queryParameters.get(name).get(i), matchers[i]); + } + } + }; + } + + /** + * Assert request query parameter values. + */ + public static RequestMatcher queryParameter(final String name, final String... expectedValues) { + return queryParameter(name, UTF_8, expectedValues); + } + + /** + * Assert request query parameter values. + */ + public static RequestMatcher queryParameter(final String name, final Charset charset, final String... expectedValues) { + return new RequestMatcher() { + @Override + public void match(ClientHttpRequest request) { + MultiValueMap queryParameters = getQueryParameters(request.getURI().toString(), charset); + assertQueryParameterValueCount(name, queryParameters, expectedValues.length); + for (int i = 0 ; i < expectedValues.length; i++) { + assertEquals("Request query parameter + [" + name + "]", + expectedValues[i], queryParameters.get(name).get(i)); + } + } + }; + } + + private static MultiValueMap getQueryParameters(String uri, Charset charset) { + String decodeUri = UriUtils.decode(uri, charset); + MultiValueMap queryParameters = UriComponentsBuilder.fromUriString(decodeUri) + .build().getQueryParams(); + return queryParameters; + } + + private static void assertQueryParameterValueCount(final String name, MultiValueMap queryParameters, int expectedCount) { + assertMultiValueMapCount("query parameter", name, queryParameters, expectedCount); + } + + private static void assertMultiValueMapCount(String type, final String name, MultiValueMap multiValueMap, int expectedCount) { + List actualValues = multiValueMap.get(name); + assertTrue("Expected " + type + " <" + name + ">", actualValues != null); + assertTrue("Expected " + type + " <" + name + "> to have at least <" + expectedCount + "> values but found " + actualValues, expectedCount <= actualValues.size()); } diff --git a/spring-test/src/test/java/org/springframework/test/web/client/match/MockRestRequestMatchersTests.java b/spring-test/src/test/java/org/springframework/test/web/client/match/MockRestRequestMatchersTests.java index 58cad79c669..03339d88fbd 100644 --- a/spring-test/src/test/java/org/springframework/test/web/client/match/MockRestRequestMatchersTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/client/match/MockRestRequestMatchersTests.java @@ -16,15 +16,20 @@ package org.springframework.test.web.client.match; +import org.junit.Test; +import org.springframework.http.HttpMethod; +import org.springframework.mock.http.client.MockClientHttpRequest; +import org.springframework.test.web.client.RequestMatcher; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; +import org.springframework.web.util.UriComponentsBuilder; + import java.net.URI; import java.util.Arrays; -import org.junit.Test; - -import org.springframework.http.HttpMethod; -import org.springframework.mock.http.client.MockClientHttpRequest; - -import static org.hamcrest.Matchers.*; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.notNullValue; +import static org.junit.Assert.assertThat; /** * Unit tests for {@link MockRestRequestMatchers}. @@ -129,4 +134,74 @@ public class MockRestRequestMatchersTests { MockRestRequestMatchers.header("foo", "bar", "baz").match(this.request); } + @Test + public void queryParameter() throws Exception { + this.request.setURI(createUriWithQueryParameters("foo", "bar", "baz")); + + RequestMatcher requestMatcher = MockRestRequestMatchers.queryParameter("foo", "bar", "baz"); + assertThat("Factory method did not create any request matcher", requestMatcher, notNullValue()); + requestMatcher.match(this.request); + } + + @Test(expected = AssertionError.class) + public void queryParameterMissing() throws Exception { + this.request.setURI(UriComponentsBuilder + .fromUriString("http://foo.com") + .path("/bar") + .build().encode() + .toUri()); + + MockRestRequestMatchers.queryParameter("foo", "bar").match(this.request); + } + + @Test(expected = AssertionError.class) + public void queryParameterMissingValue() throws Exception { + this.request.setURI(createUriWithQueryParameters("foo", "bar", "baz")); + + MockRestRequestMatchers.queryParameter("foo", "bad").match(this.request); + } + + @Test + public void queryParameterContains() throws Exception { + this.request.setURI(createUriWithQueryParameters("foo", "bar", "baz")); + + RequestMatcher requestMatcher = MockRestRequestMatchers.queryParameter("foo", containsString("ba")); + assertThat("Factory method did not create any request matcher", requestMatcher, notNullValue()); + requestMatcher.match(this.request); + } + + @Test(expected = AssertionError.class) + public void queryParameterContainsWithMissingValue() throws Exception { + this.request.setURI(createUriWithQueryParameters("foo", "bar", "baz")); + + MockRestRequestMatchers.queryParameter("foo", containsString("bx")).match(this.request); + } + + @Test + public void queryParameters() throws Exception { + this.request.setURI(createUriWithQueryParameters("foo", "bar", "baz")); + + RequestMatcher requestMatcher = MockRestRequestMatchers.queryParameter("foo", "bar", "baz"); + assertThat("Factory method did not create any request matcher", requestMatcher, notNullValue()); + requestMatcher.match(this.request); + } + + @Test(expected = AssertionError.class) + public void queryParametersWithMissingValue() throws Exception { + this.request.setURI(createUriWithQueryParameters("foo", "bar")); + + MockRestRequestMatchers.queryParameter("foo", "bar", "baz").match(this.request); + } + + + private URI createUriWithQueryParameters(String key, String ... values) { + MultiValueMap params = new LinkedMultiValueMap<>(); + params.put(key, Arrays.asList(values)); + return UriComponentsBuilder + .fromUriString("http://foo.com") + .path("/bar") + .queryParams(params) + .build().encode().toUri(); + } + } \ No newline at end of file