diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/request/MockHttpServletRequestBuilder.java b/spring-test/src/main/java/org/springframework/test/web/servlet/request/MockHttpServletRequestBuilder.java
index 9b6cf1c8fde..d88acf31f2d 100644
--- a/spring-test/src/main/java/org/springframework/test/web/servlet/request/MockHttpServletRequestBuilder.java
+++ b/spring-test/src/main/java/org/springframework/test/web/servlet/request/MockHttpServletRequestBuilder.java
@@ -28,6 +28,7 @@ import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
+import java.util.stream.Collectors;
import javax.servlet.ServletContext;
import javax.servlet.ServletRequest;
@@ -100,6 +101,9 @@ public class MockHttpServletRequestBuilder
@Nullable
private Boolean secure;
+ @Nullable
+ private String queryString = "";
+
@Nullable
private Principal principal;
@@ -354,6 +358,40 @@ public class MockHttpServletRequestBuilder
return this;
}
+ /**
+ * Add a query parameter to the {@link MockHttpServletRequest}.
+ *
If called more than once, new values get added to existing ones.
+ * @param name the parameter name
+ * @param values one or more values
+ */
+ public MockHttpServletRequestBuilder queryParam(String name, String... values) {
+ param(name, values);
+ String builder = Arrays.stream(values).map(value -> UriUtils.encode(name, StandardCharsets.UTF_8) +
+ ((value != null) ? ("=" + UriUtils.encode(value, StandardCharsets.UTF_8)) : "") + "&"
+ ).collect(Collectors.joining());
+ queryString += builder;
+ return this;
+ }
+
+ /**
+ * Add a map of query parameters to the {@link MockHttpServletRequest},
+ * for example when testing a form submission.
+ *
If called more than once, new values get added to existing ones.
+ * @param params the parameters to add
+ * @since 4.2.4
+ */
+ public MockHttpServletRequestBuilder queryParams(MultiValueMap params) {
+ params(params);
+ StringBuilder builder = new StringBuilder();
+ params.forEach((key, values) -> values.forEach(value -> {
+ builder.append(UriUtils.encode(key, StandardCharsets.UTF_8))
+ .append(((value != null) ? ("=" + UriUtils.encode(value, StandardCharsets.UTF_8)) : ""))
+ .append("&");
+ }));
+ queryString += builder.toString();
+ return this;
+ }
+
/**
* Add the given cookies to the request. Cookies are always added.
* @param cookies the cookies to add
@@ -636,13 +674,24 @@ public class MockHttpServletRequestBuilder
request.setQueryString(this.url.getRawQuery());
}
addRequestParams(request, UriComponentsBuilder.fromUri(this.url).build().getQueryParams());
-
this.parameters.forEach((name, values) -> {
for (String value : values) {
request.addParameter(name, value);
}
});
+ StringBuilder queryBuilder = new StringBuilder();
+ if (request.getQueryString() != null) {
+ queryBuilder.append(request.getQueryString());
+ }
+ if (this.queryString != null && !"".equals(this.queryString)) {
+ if (queryBuilder.length() > 0) {
+ queryBuilder.append("&");
+ }
+ queryBuilder.append(this.queryString, 0, this.queryString.length() - 1);
+ request.setQueryString(queryBuilder.toString());
+ }
+
if (this.content != null && this.content.length > 0) {
String requestContentType = request.getContentType();
if (requestContentType != null) {
diff --git a/spring-test/src/test/java/org/springframework/test/web/servlet/request/MockHttpServletRequestBuilderTests.java b/spring-test/src/test/java/org/springframework/test/web/servlet/request/MockHttpServletRequestBuilderTests.java
index 22362a33d16..34c29ce4b3c 100644
--- a/spring-test/src/test/java/org/springframework/test/web/servlet/request/MockHttpServletRequestBuilderTests.java
+++ b/spring-test/src/test/java/org/springframework/test/web/servlet/request/MockHttpServletRequestBuilderTests.java
@@ -21,6 +21,7 @@ import java.net.URI;
import java.net.URISyntaxException;
import java.nio.charset.StandardCharsets;
import java.security.Principal;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
@@ -234,6 +235,47 @@ public class MockHttpServletRequestBuilderTests {
assertThat(request.getParameter("foo[1]")).isEqualTo("baz");
}
+ @Test
+ public void requestParameterToQuery() {
+ this.builder = new MockHttpServletRequestBuilder(HttpMethod.GET, "/");
+ this.builder.queryParam("foo", "bar");
+ this.builder.queryParam("foo", "baz");
+
+ MockHttpServletRequest request = this.builder.buildRequest(this.servletContext);
+
+ assertThat(request.getParameterMap().get("foo")).isEqualTo(new String[] {"bar", "baz"});
+ assertThat(request.getQueryString()).isEqualTo("foo=bar&foo=baz");
+ }
+
+ @Test
+ public void requestParameterMapToQuery() {
+ this.builder = new MockHttpServletRequestBuilder(HttpMethod.GET, "/");
+ MultiValueMap queryParams = new LinkedMultiValueMap<>();
+ List values = new ArrayList<>();
+ values.add("bar");
+ values.add("baz");
+ queryParams.put("foo", values);
+ this.builder.queryParams(queryParams);
+
+ MockHttpServletRequest request = this.builder.buildRequest(this.servletContext);
+
+ assertThat(request.getParameterMap().get("foo")).isEqualTo(new String[] {"bar", "baz"});
+ assertThat(request.getQueryString()).isEqualTo("foo=bar&foo=baz");
+ }
+
+ @Test
+ public void requestParameterToQueryList() {
+ this.builder = new MockHttpServletRequestBuilder(HttpMethod.GET, "/");
+ this.builder.queryParam("foo[0]", "bar");
+ this.builder.queryParam("foo[1]", "baz");
+
+ MockHttpServletRequest request = this.builder.buildRequest(this.servletContext);
+
+ assertThat(request.getQueryString()).isEqualTo("foo%5B0%5D=bar&foo%5B1%5D=baz");
+ assertThat(request.getParameter("foo[0]")).isEqualTo("bar");
+ assertThat(request.getParameter("foo[1]")).isEqualTo("baz");
+ }
+
@Test
public void requestParameterFromQueryWithEncoding() {
this.builder = new MockHttpServletRequestBuilder(HttpMethod.GET, "/?foo={value}", "bar=baz");