Expose the uriTemplate used to build a MockHttpServletRequest

This commit exposes the unexpanded URI template used to build a
MockHttpServletRequest. This allows MockMvc users to retrieve that
information, in consistency with ExchangeResult in WebTestClient.

Closes gh-33509
This commit is contained in:
Stéphane Nicoll
2024-09-09 14:46:05 +02:00
parent d2b25c0378
commit e311d9848a
4 changed files with 103 additions and 23 deletions

View File

@@ -16,6 +16,7 @@
package org.springframework.test.web.servlet.assertj;
import java.net.URI;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
@@ -34,6 +35,7 @@ import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.lang.Nullable;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockServletContext;
import org.springframework.test.json.AbstractJsonContentAssert;
@@ -148,51 +150,57 @@ class MockMvcTesterTests {
@Test
void getConfiguresBuilder() {
assertThat(createMockHttpServletRequest(tester -> tester.get().uri("/hello")))
.satisfies(hasSettings(HttpMethod.GET, "/hello"));
assertThat(createMockHttpServletRequest(tester -> tester.get().uri("/hello/{id}", "world")))
.satisfies(hasSettings(HttpMethod.GET, "/hello/{id}", "/hello/world"));
}
@Test
void headConfiguresBuilder() {
assertThat(createMockHttpServletRequest(tester -> tester.head().uri("/download")))
.satisfies(hasSettings(HttpMethod.HEAD, "/download"));
assertThat(createMockHttpServletRequest(tester -> tester.head().uri("/download/{file}", "test.json")))
.satisfies(hasSettings(HttpMethod.HEAD, "/download/{file}", "/download/test.json"));
}
@Test
void postConfiguresBuilder() {
assertThat(createMockHttpServletRequest(tester -> tester.post().uri("/save")))
.satisfies(hasSettings(HttpMethod.POST, "/save"));
assertThat(createMockHttpServletRequest(tester -> tester.post().uri("/save/{id}", 123)))
.satisfies(hasSettings(HttpMethod.POST, "/save/{id}", "/save/123"));
}
@Test
void putConfiguresBuilder() {
assertThat(createMockHttpServletRequest(tester -> tester.put().uri("/save")))
.satisfies(hasSettings(HttpMethod.PUT, "/save"));
assertThat(createMockHttpServletRequest(tester -> tester.put().uri("/save/{id}", 123)))
.satisfies(hasSettings(HttpMethod.PUT, "/save/{id}", "/save/123"));
}
@Test
void patchConfiguresBuilder() {
assertThat(createMockHttpServletRequest(tester -> tester.patch().uri("/update")))
.satisfies(hasSettings(HttpMethod.PATCH, "/update"));
assertThat(createMockHttpServletRequest(tester -> tester.patch().uri("/update/{id}", 123)))
.satisfies(hasSettings(HttpMethod.PATCH, "/update/{id}", "/update/123"));
}
@Test
void deleteConfiguresBuilder() {
assertThat(createMockHttpServletRequest(tester -> tester.delete().uri("/users/42")))
.satisfies(hasSettings(HttpMethod.DELETE, "/users/42"));
assertThat(createMockHttpServletRequest(tester -> tester.delete().uri("/users/{id}", 42)))
.satisfies(hasSettings(HttpMethod.DELETE, "/users/{id}", "/users/42"));
}
@Test
void optionsConfiguresBuilder() {
assertThat(createMockHttpServletRequest(tester -> tester.options().uri("/users")))
.satisfies(hasSettings(HttpMethod.OPTIONS, "/users"));
assertThat(createMockHttpServletRequest(tester -> tester.options().uri("/users/{id}", 42)))
.satisfies(hasSettings(HttpMethod.OPTIONS, "/users/{id}", "/users/42"));
}
@Test
void methodConfiguresBuilderWithCustomMethod() {
HttpMethod customMethod = HttpMethod.valueOf("CUSTOM");
assertThat(createMockHttpServletRequest(tester -> tester.method(customMethod).uri("/hello")))
.satisfies(hasSettings(customMethod, "/hello"));
.satisfies(hasSettings(customMethod, "/hello", "/hello"));
}
@Test
void methodConfiguresBuilderWithFullURI() {
assertThat(createMockHttpServletRequest(tester -> tester.get().uri(URI.create("/hello/world"))))
.satisfies(hasSettings(HttpMethod.GET, null, "/hello/world"));
}
private MockHttpServletRequest createMockHttpServletRequest(Function<MockMvcTester, MockMvcRequestBuilder> builder) {
@@ -200,9 +208,10 @@ class MockMvcTesterTests {
return builder.apply(mockMvcTester).buildRequest(this.servletContext);
}
private Consumer<MockHttpServletRequest> hasSettings(HttpMethod method, String uri) {
private Consumer<MockHttpServletRequest> hasSettings(HttpMethod method, @Nullable String uriTemplate, String uri) {
return request -> {
assertThat(request.getMethod()).isEqualTo(method.name());
assertThat(request.getUriTemplate()).isEqualTo(uriTemplate);
assertThat(request.getRequestURI()).isEqualTo(uri);
};
}

View File

@@ -16,6 +16,8 @@
package org.springframework.test.web.servlet.request;
import java.net.URI;
import jakarta.servlet.ServletContext;
import org.junit.jupiter.api.Test;
@@ -34,16 +36,53 @@ class AbstractMockHttpServletRequestBuilderTests {
private final ServletContext servletContext = new MockServletContext();
@Test
void uriTemplateSetsRequestsUrlAndTemplateConsistently() {
MockHttpServletRequest request = buildRequest(new TestRequestBuilder(HttpMethod.GET).uri("/hotels/{id}", 42));
assertThat(request.getRequestURL().toString()).isEqualTo("http://localhost/hotels/42");
assertThat(request.getUriTemplate()).isEqualTo("/hotels/{id}");
}
@Test
void mergeUriWhenUriIsNotSet() {
TestRequestBuilder parentBuilder = new TestRequestBuilder(HttpMethod.GET).uri("/test");
void uriSetsRequestsUrlAndTemplateConsistently() {
MockHttpServletRequest request = buildRequest(new TestRequestBuilder(HttpMethod.GET).uri("/hotels/{id}", 42)
.uri(URI.create("/hotels/25")));
assertThat(request.getRequestURL().toString()).isEqualTo("http://localhost/hotels/25");
assertThat(request.getUriTemplate()).isNull();
}
@Test
void mergeUriTemplateWhenUriTemplateIsNotSet() {
TestRequestBuilder parentBuilder = new TestRequestBuilder(HttpMethod.GET).uri("/hotels/{id}", 42);
TestRequestBuilder builder = new TestRequestBuilder(HttpMethod.POST);
builder.merge(parentBuilder);
MockHttpServletRequest request = buildRequest(builder);
assertThat(request.getRequestURI()).isEqualTo("/test");
assertThat(request.getMethod()).isEqualTo(HttpMethod.POST.name());
assertThat(request.getUriTemplate()).isEqualTo("/hotels/{id}");
assertThat(request.getRequestURL().toString()).isEqualTo("http://localhost/hotels/42");
}
@Test
void mergeUriTemplateWhenUriIsSetDoesNotMergeUriTemplate() {
TestRequestBuilder parentBuilder = new TestRequestBuilder(HttpMethod.GET).uri("/hotels/{id}", 42);
TestRequestBuilder builder = new TestRequestBuilder(HttpMethod.POST).uri(URI.create("/hotels/35"));
builder.merge(parentBuilder);
MockHttpServletRequest request = buildRequest(builder);
assertThat(request.getUriTemplate()).isNull();
assertThat(request.getRequestURL().toString()).isEqualTo("http://localhost/hotels/35");
}
@Test
void mergeUriTemplateWhenUriTemplateIsSetDoesNotMergeUriTemplate() {
TestRequestBuilder parentBuilder = new TestRequestBuilder(HttpMethod.GET).uri("/hotels/{id}", 42);
TestRequestBuilder builder = new TestRequestBuilder(HttpMethod.POST).uri("/users/{id}", 25);
builder.merge(parentBuilder);
MockHttpServletRequest request = buildRequest(builder);
assertThat(request.getUriTemplate()).isEqualTo("/users/{id}");
assertThat(request.getRequestURL().toString()).isEqualTo("http://localhost/users/25");
}
@Test