Skip to content

Commit e04a756

Browse files
committed
Support AntPathMatch URLs in URL ResultMatchers
Prior to this commit, one could only match exact URLs in redirectedUrl and forwardedUrl ResultMatchers. When creating a resource with a REST service, URLs often contain the id the new resource, like "/resource/12". This commit updates those ResultMatchers to support both exact matches and AntPath matches, using new methods. The former URL then can be tested against "/resource/*" in MVC tests. Issue: SPR-10789
1 parent 4ca7d89 commit e04a756

File tree

3 files changed

+147
-2
lines changed

3 files changed

+147
-2
lines changed

spring-test-mvc/src/main/java/org/springframework/test/web/servlet/result/MockMvcResultMatchers.java

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2012 the original author or authors.
2+
* Copyright 2002-2013 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.
@@ -17,6 +17,7 @@
1717
package org.springframework.test.web.servlet.result;
1818

1919
import static org.springframework.test.util.AssertionErrors.assertEquals;
20+
import static org.springframework.test.util.AssertionErrors.assertTrue;
2021

2122
import java.util.Map;
2223

@@ -25,6 +26,7 @@
2526
import org.hamcrest.Matcher;
2627
import org.springframework.test.web.servlet.MvcResult;
2728
import org.springframework.test.web.servlet.ResultMatcher;
29+
import org.springframework.util.AntPathMatcher;
2830

2931
/**
3032
* Static, factory methods for {@link ResultMatcher}-based result actions.
@@ -33,6 +35,7 @@
3335
* favorite. To navigate, open the Preferences and type "favorites".
3436
*
3537
* @author Rossen Stoyanchev
38+
* @author Brian Clozel
3639
* @since 3.2
3740
*/
3841
public abstract class MockMvcResultMatchers {
@@ -78,6 +81,8 @@ public static FlashAttributeResultMatchers flash() {
7881

7982
/**
8083
* Asserts the request was forwarded to the given URL.
84+
* This methods accepts only exact matches.
85+
* @param expectedUrl the exact URL expected
8186
*/
8287
public static ResultMatcher forwardedUrl(final String expectedUrl) {
8388
return new ResultMatcher() {
@@ -88,8 +93,35 @@ public void match(MvcResult result) {
8893
};
8994
}
9095

96+
/**
97+
* Asserts the request was forwarded to the given URL.
98+
* This methods accepts {@link org.springframework.util.AntPathMatcher} expressions.
99+
*
100+
* <p>When trying to match against "?" or "*" exactly, those characters
101+
* should be escaped (e.g. "\\?" and "\\*")
102+
*
103+
* @param expectedUrl an AntPath expression to match against
104+
* @see org.springframework.util.AntPathMatcher
105+
* @since 4.0
106+
*/
107+
public static ResultMatcher forwardedUrlPattern(final String expectedUrl) {
108+
return new ResultMatcher() {
109+
110+
private final AntPathMatcher pathMatcher = new AntPathMatcher();
111+
112+
@Override
113+
public void match(MvcResult result) {
114+
assertTrue("AntPath expression",pathMatcher.isPattern(expectedUrl));
115+
assertTrue("Forwarded URL",
116+
pathMatcher.match(expectedUrl, result.getResponse().getForwardedUrl()));
117+
}
118+
};
119+
}
120+
91121
/**
92122
* Asserts the request was redirected to the given URL.
123+
* This methods accepts only exact matches.
124+
* @param expectedUrl the exact URL expected
93125
*/
94126
public static ResultMatcher redirectedUrl(final String expectedUrl) {
95127
return new ResultMatcher() {
@@ -100,6 +132,31 @@ public void match(MvcResult result) {
100132
};
101133
}
102134

135+
/**
136+
* Asserts the request was redirected to the given URL.
137+
* This methods accepts {@link org.springframework.util.AntPathMatcher} expressions.
138+
*
139+
* <p>When trying to match against "?" or "*" exactly, those characters
140+
* should be escaped (e.g. "\\?" and "\\*")
141+
*
142+
* @param expectedUrl an AntPath expression to match against
143+
* @see org.springframework.util.AntPathMatcher
144+
* @since 4.0
145+
*/
146+
public static ResultMatcher redirectedUrlPattern(final String expectedUrl) {
147+
return new ResultMatcher() {
148+
149+
private final AntPathMatcher pathMatcher = new AntPathMatcher();
150+
151+
@Override
152+
public void match(MvcResult result) {
153+
assertTrue("AntPath expression",pathMatcher.isPattern(expectedUrl));
154+
assertTrue("Redirected URL",
155+
pathMatcher.match(expectedUrl, result.getResponse().getRedirectedUrl()));
156+
}
157+
};
158+
}
159+
103160
/**
104161
* Access to response status assertions.
105162
*/
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
/*
2+
* Copyright 2002-2013 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.test.web.servlet.result;
17+
18+
import org.junit.Test;
19+
import org.springframework.mock.web.MockHttpServletResponse;
20+
import org.springframework.test.web.servlet.StubMvcResult;
21+
22+
/**
23+
* @author Brian Clozel
24+
*/
25+
public class MockMvcResultMatchersTests {
26+
27+
@Test
28+
public void testRedirect() throws Exception {
29+
MockMvcResultMatchers.redirectedUrl("/resource/1")
30+
.match(getRedirectedUrlStubMvcResult("/resource/1"));
31+
}
32+
33+
@Test
34+
public void testRedirectPattern() throws Exception {
35+
MockMvcResultMatchers.redirectedUrlPattern("/resource/*")
36+
.match(getRedirectedUrlStubMvcResult("/resource/1"));
37+
}
38+
39+
@Test( expected = java.lang.AssertionError.class)
40+
public void testFailRedirectPattern() throws Exception {
41+
MockMvcResultMatchers.redirectedUrlPattern("/resource/")
42+
.match(getRedirectedUrlStubMvcResult("/resource/1"));
43+
}
44+
45+
@Test
46+
public void testForward() throws Exception {
47+
MockMvcResultMatchers.forwardedUrl("/api/resource/1")
48+
.match(getForwardedUrlStubMvcResult("/api/resource/1"));
49+
}
50+
51+
@Test
52+
public void testForwardEscapedChars() throws Exception {
53+
MockMvcResultMatchers.forwardedUrl("/api/resource/1?arg=value")
54+
.match(getForwardedUrlStubMvcResult("/api/resource/1?arg=value"));
55+
}
56+
57+
@Test
58+
public void testForwardPattern() throws Exception {
59+
MockMvcResultMatchers.forwardedUrlPattern("/api/**/?")
60+
.match(getForwardedUrlStubMvcResult("/api/resource/1"));
61+
}
62+
63+
private StubMvcResult getRedirectedUrlStubMvcResult(String redirectUrl) throws Exception {
64+
MockHttpServletResponse response = new MockHttpServletResponse();
65+
response.sendRedirect(redirectUrl);
66+
StubMvcResult mvcResult = new StubMvcResult(null, null, null, null, null, null, response);
67+
return mvcResult;
68+
}
69+
70+
private StubMvcResult getForwardedUrlStubMvcResult(String forwardedUrl) {
71+
MockHttpServletResponse response = new MockHttpServletResponse();
72+
response.setForwardedUrl(forwardedUrl);
73+
StubMvcResult mvcResult = new StubMvcResult(null, null, null, null, null, null, response);
74+
return mvcResult;
75+
}
76+
77+
}

spring-test-mvc/src/test/java/org/springframework/test/web/servlet/samples/standalone/resultmatchers/UrlAssertionTests.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2012 the original author or authors.
2+
* Copyright 2002-2013 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.
@@ -18,7 +18,9 @@
1818

1919
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
2020
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.forwardedUrl;
21+
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.forwardedUrlPattern;
2122
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.redirectedUrl;
23+
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.redirectedUrlPattern;
2224
import static org.springframework.test.web.servlet.setup.MockMvcBuilders.standaloneSetup;
2325

2426
import org.junit.Before;
@@ -46,11 +48,20 @@ public void testRedirect() throws Exception {
4648
this.mockMvc.perform(get("/persons")).andExpect(redirectedUrl("/persons/1"));
4749
}
4850

51+
@Test
52+
public void testRedirectPattern() throws Exception {
53+
this.mockMvc.perform(get("/persons")).andExpect(redirectedUrlPattern("/persons/*"));
54+
}
55+
4956
@Test
5057
public void testForward() throws Exception {
5158
this.mockMvc.perform(get("/")).andExpect(forwardedUrl("/home"));
5259
}
5360

61+
@Test
62+
public void testForwardPattern() throws Exception {
63+
this.mockMvc.perform(get("/")).andExpect(forwardedUrlPattern("/ho?e"));
64+
}
5465

5566
@Controller
5667
private static class SimpleController {

0 commit comments

Comments
 (0)