diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/result/MockMvcResultMatchers.java b/spring-test/src/main/java/org/springframework/test/web/servlet/result/MockMvcResultMatchers.java index 60122452826..b5cbd3a1563 100644 --- a/spring-test/src/main/java/org/springframework/test/web/servlet/result/MockMvcResultMatchers.java +++ b/spring-test/src/main/java/org/springframework/test/web/servlet/result/MockMvcResultMatchers.java @@ -85,7 +85,8 @@ public abstract class MockMvcResultMatchers { /** * Asserts the request was forwarded to the given URL. *

This method accepts only exact matches. - * @param expectedUrl the exact URL expected + * @param expectedUrl the exact URL expected; or {@code null} to assert + * that no forwarding occurred */ public static ResultMatcher forwardedUrl(@Nullable String expectedUrl) { return result -> assertEquals("Forwarded URL", expectedUrl, result.getResponse().getForwardedUrl()); @@ -124,9 +125,10 @@ public abstract class MockMvcResultMatchers { /** * Asserts the request was redirected to the given URL. *

This method accepts only exact matches. - * @param expectedUrl the exact URL expected + * @param expectedUrl the exact URL expected; or {@code null} to assert + * that no redirect occurred */ - public static ResultMatcher redirectedUrl(String expectedUrl) { + public static ResultMatcher redirectedUrl(@Nullable String expectedUrl) { return result -> assertEquals("Redirected URL", expectedUrl, result.getResponse().getRedirectedUrl()); } diff --git a/spring-test/src/test/java/org/springframework/test/web/servlet/result/MockMvcResultMatchersTests.java b/spring-test/src/test/java/org/springframework/test/web/servlet/result/MockMvcResultMatchersTests.java index bae29cbf992..7e1f4993f5c 100644 --- a/spring-test/src/test/java/org/springframework/test/web/servlet/result/MockMvcResultMatchersTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/servlet/result/MockMvcResultMatchersTests.java @@ -39,11 +39,17 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. class MockMvcResultMatchersTests { @Test - void redirect() throws Exception { + void redirect() { assertThatCode(() -> redirectedUrl("/resource/1").match(redirectedUrlStub("/resource/1"))) .doesNotThrowAnyException(); } + @Test // gh-37230 + void redirectWithNullAssertsNoRedirectOccurred() { + assertThatCode(() -> redirectedUrl(null).match(noRedirectOrForwardStub())) + .doesNotThrowAnyException(); + } + @Test void redirectNonMatching() { assertThatExceptionOfType(AssertionError.class) @@ -58,6 +64,13 @@ class MockMvcResultMatchersTests { .withMessageEndingWith("expected: but was:"); } + @Test // gh-37230 + void redirectWithNullNonMatchingBecauseRedirectOccurred() { + assertThatExceptionOfType(AssertionError.class) + .isThrownBy(() -> redirectedUrl(null).match(redirectedUrlStub("/resource/1"))) + .withMessageEndingWith("expected: but was:"); + } + @Test void redirectWithUrlTemplate() { assertThatCode(() -> redirectedUrlTemplate("/orders/{orderId}/items/{itemId}", 1, 2).match(redirectedUrlStub("/orders/1/items/2"))) @@ -85,11 +98,17 @@ class MockMvcResultMatchersTests { } @Test - void forward() throws Exception { + void forward() { assertThatCode(() -> forwardedUrl("/api/resource/1").match(forwardedUrlStub("/api/resource/1"))) .doesNotThrowAnyException(); } + @Test // gh-22155 + void forwardWithNullAssertsNoForwardingOccurred() { + assertThatCode(() -> forwardedUrl(null).match(noRedirectOrForwardStub())) + .doesNotThrowAnyException(); + } + @Test void forwardNonMatching() { assertThatExceptionOfType(AssertionError.class) @@ -104,6 +123,13 @@ class MockMvcResultMatchersTests { .withMessage("Forwarded URL 'null' does not match the expected URL pattern '/resource/*'"); } + @Test // gh-22155 + void forwardWithNullNonMatchingBecauseForwardingOccurred() { + assertThatExceptionOfType(AssertionError.class) + .isThrownBy(() -> forwardedUrl(null).match(forwardedUrlStub("/resource/1"))) + .withMessageEndingWith("expected: but was:"); + } + @Test void forwardWithQueryString() { assertThatCode(() -> forwardedUrl("/api/resource/1?arg=value").match(forwardedUrlStub("/api/resource/1?arg=value"))) @@ -136,6 +162,10 @@ class MockMvcResultMatchersTests { .withMessage("Forwarded URL 'null' does not match the expected URL pattern '/resource/*'"); } + private StubMvcResult noRedirectOrForwardStub() { + return new StubMvcResult(null, null, null, null, null, null, new MockHttpServletResponse()); + } + private StubMvcResult redirectedUrlStub(String redirectUrl) throws Exception { MockHttpServletResponse response = new MockHttpServletResponse(); response.sendRedirect(redirectUrl);