Skip to content

Commit d6e35cf

Browse files
committed
Introduce queryParamCount() in MockRestRequestMatchers
Closes gh-34703
1 parent 1898912 commit d6e35cf

File tree

2 files changed

+52
-4
lines changed

2 files changed

+52
-4
lines changed

Diff for: spring-test/src/main/java/org/springframework/test/web/client/match/MockRestRequestMatchers.java

+23-2
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import java.net.URI;
2020
import java.util.List;
2121
import java.util.Map;
22+
import java.util.Set;
2223

2324
import javax.xml.xpath.XPathExpressionException;
2425

@@ -130,6 +131,7 @@ public static RequestMatcher requestTo(URI uri) {
130131
* @since 5.3.27
131132
* @see #queryParam(String, Matcher...)
132133
* @see #queryParam(String, String...)
134+
* @see #queryParamCount(int)
133135
*/
134136
public static RequestMatcher queryParamList(String name, Matcher<? super List<String>> matcher) {
135137
return request -> {
@@ -158,6 +160,7 @@ public static RequestMatcher queryParamList(String name, Matcher<? super List<St
158160
* parameter value
159161
* @see #queryParamList(String, Matcher)
160162
* @see #queryParam(String, String...)
163+
* @see #queryParamCount(int)
161164
*/
162165
@SafeVarargs
163166
@SuppressWarnings("NullAway") // Dataflow analysis limitation
@@ -187,6 +190,7 @@ public static RequestMatcher queryParam(String name, Matcher<? super String>...
187190
* parameter value
188191
* @see #queryParamList(String, Matcher)
189192
* @see #queryParam(String, Matcher...)
193+
* @see #queryParamCount(int)
190194
*/
191195
@SuppressWarnings("NullAway") // Dataflow analysis limitation
192196
public static RequestMatcher queryParam(String name, String... expectedValues) {
@@ -199,6 +203,25 @@ public static RequestMatcher queryParam(String name, String... expectedValues) {
199203
};
200204
}
201205

206+
/**
207+
* Assert the number of query parameters present in the request.
208+
* @param expectedCount the number of expected query parameters
209+
* @since 7.0
210+
* @see #queryParamList(String, Matcher)
211+
* @see #queryParam(String, Matcher...)
212+
* @see #queryParam(String, String...)
213+
*/
214+
@SuppressWarnings("NullAway") // Dataflow analysis limitation
215+
public static RequestMatcher queryParamCount(int expectedCount) {
216+
return request -> {
217+
Set<String> parameterNames = getQueryParams(request).keySet();
218+
int actualCount = parameterNames.size();
219+
if (expectedCount != actualCount) {
220+
fail("Expected %d query parameter(s) but found %d: %s".formatted(expectedCount, actualCount, parameterNames));
221+
}
222+
};
223+
}
224+
202225
private static MultiValueMap<String, String> getQueryParams(ClientHttpRequest request) {
203226
return UriComponentsBuilder.fromUri(request.getURI()).build().getQueryParams();
204227
}
@@ -359,7 +382,6 @@ public static XpathRequestMatchers xpath(String expression, Map<String, String>
359382

360383

361384
private static void assertValueCount(String name, MultiValueMap<String, String> map, int count) {
362-
363385
List<String> values = map.get(name);
364386
String message = "Expected query param <" + name + ">";
365387
if (values == null) {
@@ -371,7 +393,6 @@ else if (count > values.size()) {
371393
}
372394

373395
private static void assertValueCount(String name, HttpHeaders headers, int count) {
374-
375396
List<String> values = headers.get(name);
376397
String message = "Expected header <" + name + ">";
377398
if (values == null) {

Diff for: spring-test/src/test/java/org/springframework/test/web/client/match/MockRestRequestMatchersTests.java

+29-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2024 the original author or authors.
2+
* Copyright 2002-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -287,7 +287,6 @@ void queryParamContainsWithMissingValue() {
287287
.withMessageContaining("was \"bar\"");
288288
}
289289

290-
291290
@Test
292291
void queryParamListMissing() {
293292
assertThatAssertionError()
@@ -353,6 +352,34 @@ void queryParamListDoesNotHideQueryParamWithSingleMatcher() throws IOException {
353352
"but: was <[bar, baz]>");
354353
}
355354

355+
@Test // gh-34703
356+
void queryParamCount() throws Exception {
357+
this.request.setURI(URI.create("http://www.foo.example/a"));
358+
MockRestRequestMatchers.queryParamCount(0).match(this.request);
359+
360+
this.request.setURI(URI.create("http://www.foo.example/a?"));
361+
MockRestRequestMatchers.queryParamCount(0).match(this.request);
362+
363+
this.request.setURI(URI.create("http://www.foo.example/a?foo=1"));
364+
MockRestRequestMatchers.queryParamCount(1).match(this.request);
365+
366+
this.request.setURI(URI.create("http://www.foo.example/a?foo=1&foo=2"));
367+
MockRestRequestMatchers.queryParamCount(1).match(this.request);
368+
369+
this.request.setURI(URI.create("http://www.foo.example/a?foo=1&baz=2"));
370+
MockRestRequestMatchers.queryParamCount(2).match(this.request);
371+
}
372+
373+
@Test // gh-34703
374+
void queryParamCountMismatch() {
375+
this.request.setURI(URI.create("http://www.foo.example/a?foo=1&baz=2"));
376+
377+
assertThatAssertionError()
378+
.isThrownBy(() -> MockRestRequestMatchers.queryParamCount(1).match(this.request))
379+
.withMessage("Expected 1 query parameter(s) but found 2: [foo, baz]");
380+
}
381+
382+
356383
private static ThrowableTypeAssert<AssertionError> assertThatAssertionError() {
357384
return assertThatExceptionOfType(AssertionError.class);
358385
}

0 commit comments

Comments
 (0)