Skip to content

Commit b97e047

Browse files
committed
Polish server-side support
Introduce new MockMvcBuilderSupport base class that instantiates MockMvc and the TestDispatcherServlet with AbstractMockMvcBuilder sub-class actually implements the MockMvcBuilders interface. Replace ResultHandler classes for printing debug information with just one PrintingResultHandler base class. Javadoc updates.
1 parent f971a2d commit b97e047

25 files changed

+544
-552
lines changed

src/main/java/org/springframework/test/web/server/DefaultMvcResult.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
* @author Rossen Stoyanchev
2929
* @author Rob Winch
3030
*/
31-
public class DefaultMvcResult implements MvcResult {
31+
class DefaultMvcResult implements MvcResult {
3232

3333
private final MockHttpServletRequest mockRequest;
3434

@@ -42,6 +42,10 @@ public class DefaultMvcResult implements MvcResult {
4242

4343
private Exception resolvedException;
4444

45+
46+
/**
47+
* Create a new instance with the given request and response.
48+
*/
4549
public DefaultMvcResult(MockHttpServletRequest request, MockHttpServletResponse response) {
4650
this.mockRequest = request;
4751
this.mockResponse = response;

src/main/java/org/springframework/test/web/server/MockMvc.java

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,12 @@
2929
/**
3030
* <strong>Main entry point for server-side Spring MVC test support.</strong>
3131
*
32-
* <p>Example, assuming static imports of {@code MockMvcBuilders.*},
33-
* {@code MockMvcRequestBuilders.*} and {@code MockMvcResultMatchers.*}:
32+
* <p>Below is an example:
3433
*
3534
* <pre>
35+
* static imports:
36+
* MockMvcBuilders.*, MockMvcRequestBuilders.*, MockMvcResultMatchers.*
37+
*
3638
* MockMvc mockMvc =
3739
* annotationConfigMvcSetup(TestConfiguration.class)
3840
* .configureWarRootDir("src/main/webapp", false).build()
@@ -46,7 +48,7 @@
4648
* @author Rossen Stoyanchev
4749
* @author Rob Winch
4850
*/
49-
public class MockMvc {
51+
public final class MockMvc {
5052

5153
static String MVC_RESULT_ATTRIBUTE = MockMvc.class.getName().concat(".MVC_RESULT_ATTRIBUTE");
5254

@@ -62,39 +64,53 @@ public class MockMvc {
6264

6365

6466
/**
65-
* Protected constructor not for direct instantiation.
67+
* Private constructor, not for direct instantiation.
6668
* @see org.springframework.test.web.server.setup.MockMvcBuilders
6769
*/
68-
protected MockMvc(MockFilterChain filterChain, ServletContext servletContext) {
70+
MockMvc(MockFilterChain filterChain, ServletContext servletContext) {
6971
Assert.notNull(servletContext, "A ServletContext is required");
7072
Assert.notNull(filterChain, "A MockFilterChain is required");
7173

7274
this.filterChain = filterChain;
7375
this.servletContext = servletContext;
7476
}
7577

76-
protected void setDefaultRequest(RequestBuilder requestBuilder) {
78+
/**
79+
* A default request builder merged into every performed request.
80+
* @see org.springframework.test.web.server.setup.AbstractMockMvcBuilder#defaultRequest(RequestBuilder)
81+
*/
82+
void setDefaultRequest(RequestBuilder requestBuilder) {
7783
this.defaultRequestBuilder = requestBuilder;
7884
}
7985

80-
protected void setDefaultResultMatchers(List<ResultMatcher> resultMatchers) {
86+
/**
87+
* Expectations to assert after every performed request.
88+
* @see org.springframework.test.web.server.setup.AbstractMockMvcBuilder#alwaysExpect(ResultMatcher)
89+
*/
90+
void setGlobalResultMatchers(List<ResultMatcher> resultMatchers) {
8191
Assert.notNull(resultMatchers, "resultMatchers is required");
8292
this.defaultResultMatchers = resultMatchers;
8393
}
8494

85-
protected void setDefaultResultHandlers(List<ResultHandler> resultHandlers) {
95+
/**
96+
* General actions to apply after every performed request.
97+
* @see org.springframework.test.web.server.setup.AbstractMockMvcBuilder#alwaysDo(ResultHandler)
98+
*/
99+
void setGlobalResultHandlers(List<ResultHandler> resultHandlers) {
86100
Assert.notNull(resultHandlers, "resultHandlers is required");
87101
this.defaultResultHandlers = resultHandlers;
88102
}
89103

90104
/**
91-
* Execute a request and return a {@link ResultActions} instance that wraps
92-
* the results and enables further actions such as setting up expectations.
105+
* Perform a request and return a type that allows chaining further
106+
* actions, such as asserting expectations, on the result.
93107
*
94108
* @param requestBuilder used to prepare the request to execute;
95109
* see static factory methods in
96110
* {@link org.springframework.test.web.server.request.MockMvcRequestBuilders}
97-
* @return A ResultActions instance; never {@code null}
111+
*
112+
* @return an instance of {@link ResultActions}; never {@code null}
113+
*
98114
* @see org.springframework.test.web.server.request.MockMvcRequestBuilders
99115
* @see org.springframework.test.web.server.result.MockMvcResultMatchers
100116
*/
@@ -145,4 +161,5 @@ private void applyDefaultResultActions(MvcResult mvcResult) throws Exception {
145161
handler.handle(mvcResult);
146162
}
147163
}
164+
148165
}

src/main/java/org/springframework/test/web/server/setup/MockMvcBuilder.java renamed to src/main/java/org/springframework/test/web/server/MockMvcBuilder.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,13 @@
1414
* limitations under the License.
1515
*/
1616

17-
package org.springframework.test.web.server.setup;
18-
19-
import org.springframework.test.web.server.MockMvc;
17+
package org.springframework.test.web.server;
2018

2119
/**
22-
* A contract for building a {@link MockMvc} instance.
20+
* Builds a {@link MockMvc}.
21+
*
22+
* <p>See static, factory methods in
23+
* {@code org.springframework.test.web.server.setup.MockMvcBuilders}.
2324
*
2425
* @author Rossen Stoyanchev
2526
*/
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
/*
2+
* Copyright 2011-2012 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+
17+
package org.springframework.test.web.server;
18+
19+
import java.util.List;
20+
21+
import javax.servlet.Filter;
22+
import javax.servlet.ServletContext;
23+
import javax.servlet.ServletException;
24+
25+
import org.springframework.core.NestedRuntimeException;
26+
import org.springframework.mock.web.MockServletConfig;
27+
import org.springframework.web.context.WebApplicationContext;
28+
29+
/**
30+
* Base class for MockMvc builder implementations, providing the capability to
31+
* create a {@link MockMvc} instance.
32+
*
33+
* <p>{@link org.springframework.test.web.server.setup.AbstractMockMvcBuilder},
34+
* which derives from this class, provides a concrete {@code build} method,
35+
* and delegates to abstract methods to obtain a {@link WebApplicationContext}.
36+
*
37+
* @author Rossen Stoyanchev
38+
* @author Rob Winch
39+
*/
40+
public abstract class MockMvcBuilderSupport {
41+
42+
protected MockMvc createMockMvc(Filter[] filters, MockServletConfig servletConfig,
43+
WebApplicationContext webAppContext, RequestBuilder defaultRequestBuilder,
44+
List<ResultMatcher> globalResultMatchers, List<ResultHandler> globalResultHandlers) {
45+
46+
ServletContext servletContext = webAppContext.getServletContext();
47+
48+
TestDispatcherServlet dispatcherServlet = new TestDispatcherServlet(webAppContext);
49+
try {
50+
dispatcherServlet.init(servletConfig);
51+
}
52+
catch (ServletException ex) {
53+
// should never happen..
54+
throw new MockMvcBuildException("Failed to initialize TestDispatcherServlet", ex);
55+
}
56+
57+
MockFilterChain filterChain = new MockFilterChain(dispatcherServlet, filters);
58+
59+
MockMvc mockMvc = new MockMvc(filterChain, servletContext);
60+
mockMvc.setDefaultRequest(defaultRequestBuilder);
61+
mockMvc.setGlobalResultMatchers(globalResultMatchers);
62+
mockMvc.setGlobalResultHandlers(globalResultHandlers);
63+
64+
return mockMvc;
65+
}
66+
67+
68+
@SuppressWarnings("serial")
69+
private static class MockMvcBuildException extends NestedRuntimeException {
70+
71+
public MockMvcBuildException(String msg, Throwable cause) {
72+
super(msg, cause);
73+
}
74+
}
75+
76+
}

src/main/java/org/springframework/test/web/server/RequestBuilder.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55
import org.springframework.mock.web.MockHttpServletRequest;
66

77
/**
8-
* A contract to build a {@link MockHttpServletRequest}.
8+
* Builds a {@link MockHttpServletRequest}.
99
*
10-
* <p>See static factory methods in
10+
* <p>See static, factory methods in
1111
* {@code org.springframework.test.web.server.request.MockMvcRequestBuilders}.
1212
*
1313
* @author Arjen Poutsma
@@ -19,7 +19,6 @@ public interface RequestBuilder {
1919
* Build the request.
2020
*
2121
* @param servletContext the {@link ServletContext} to use to create the request
22-
*
2322
* @return the request
2423
*/
2524
MockHttpServletRequest buildRequest(ServletContext servletContext);

src/main/java/org/springframework/test/web/server/ResultActions.java

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,12 @@
1717
package org.springframework.test.web.server;
1818

1919
/**
20-
* A contract for specifying some actions on the results of an executed request.
20+
* Allows applying actions, such as expectations, on the result of an executed
21+
* request.
2122
*
2223
* <p>See static factory methods in
23-
* {@code org.springframework.test.web.server.result.MockMvcResultMatchers} and
24-
* {@code org.springframework.test.web.server.result.MockMvcResultHandlers}.
24+
* {@code org.springframework.test.web.server.result.MockMvcResultMatchers}
25+
* {@code org.springframework.test.web.server.result.MockMvcResultHandlers}
2526
*
2627
* @author Rossen Stoyanchev
2728
*/
@@ -30,7 +31,7 @@ public interface ResultActions {
3031
/**
3132
* Provide an expectation. For example:
3233
* <pre>
33-
* // Assuming static import of MockMvcResultMatchers.*
34+
* static imports: MockMvcRequestBuilders.*, MockMvcResultMatchers.*
3435
*
3536
* mockMvc.perform(get("/person/1"))
3637
* .andExpect(status.isOk())
@@ -51,18 +52,15 @@ public interface ResultActions {
5152
/**
5253
* Provide a general action. For example:
5354
* <pre>
54-
* // Assuming static imports of MockMvcResultHandlers.* and MockMvcResultMatchers.*
55+
* static imports: MockMvcRequestBuilders.*, MockMvcResultMatchers.*
5556
*
56-
* mockMvc.perform(get("/form"))
57-
* .andDo(print()) // Print the results
58-
* .andExpect(status.isOk())
59-
* .andExpect(contentType(MediaType.APPLICATION_JSON));
57+
* mockMvc.perform(get("/form")).andDo(print());
6058
* </pre>
6159
*/
6260
ResultActions andDo(ResultHandler handler) throws Exception;
6361

6462
/**
65-
* Return the result of the executed request for direct inspection.
63+
* Return the result of the executed request for direct access to the results.
6664
*
6765
* @return the result of the request
6866
*/

src/main/java/org/springframework/test/web/server/ResultHandler.java

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,22 +17,30 @@
1717
package org.springframework.test.web.server;
1818

1919
/**
20-
* A contract for a generic result action as opposed to asserting an expectation
21-
* via {@link ResultMatcher}.
20+
* Executes a generic action (e.g. printing debug information) on the result of
21+
* an executed request.
2222
*
2323
* <p>See static factory methods in
2424
* {@code org.springframework.test.web.server.result.MockMvcResultHandlers}.
2525
*
26+
* <p>Example:
27+
*
28+
* <pre>
29+
* static imports: MockMvcRequestBuilders.*, MockMvcResultHandlers.*
30+
*
31+
* mockMvc.perform(get("/form")).andDo(print());
32+
* </pre>
33+
*
2634
* @author Rossen Stoyanchev
2735
*/
2836
public interface ResultHandler {
2937

3038
/**
31-
* Apply an action on the result of an executed Spring MVC request.
39+
* Apply the action on the given result.
3240
*
33-
* @param mvcResult the result of the executed request
41+
* @param result the result of the executed request
3442
* @throws Exception if a failure occurs
3543
*/
36-
void handle(MvcResult mvcResult) throws Exception;
44+
void handle(MvcResult result) throws Exception;
3745

3846
}

src/main/java/org/springframework/test/web/server/ResultMatcher.java

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,16 @@
1717
package org.springframework.test.web.server;
1818

1919
/**
20-
* A contract to match the results of an executed request against some expectation.
20+
* Matches the result of an executed request against some expectation.
2121
*
2222
* <p>See static factory methods in
2323
* {@code org.springframework.test.web.server.result.MockMvcResultMatchers}.
2424
*
25-
* <p>Example, assuming a static import of {@code MockMvcRequestBuilders.*} and
26-
* {@code MockMvcResultMatchers.*}:
25+
* <p>Example:
2726
*
2827
* <pre>
28+
* static imports: MockMvcRequestBuilders.*, MockMvcResultMatchers.*
29+
*
2930
* mockMvc.perform(get("/form"))
3031
* .andExpect(status.isOk())
3132
* .andExpect(content().mimeType(MediaType.APPLICATION_JSON));
@@ -36,11 +37,11 @@
3637
public interface ResultMatcher {
3738

3839
/**
39-
* Match the result of an executed Spring MVC request to an expectation.
40+
* Assert the result of an executed request.
4041
*
4142
* @param mvcResult the result of the executed request
4243
* @throws Exception if a failure occurs
4344
*/
44-
void match(MvcResult mvcResult) throws Exception;
45+
void match(MvcResult result) throws Exception;
4546

4647
}

src/main/java/org/springframework/test/web/server/TestDispatcherServlet.java

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,18 +26,18 @@
2626
import org.springframework.web.servlet.ModelAndView;
2727

2828
/**
29-
* A sub-class of {@code DispatcherServlet} that saves the results of processing
30-
* a request in an {@link MvcResult}. The {@code MvcResult} instance is stored
31-
* the request attribute {@link TestDispatcherServlet#MVC_RESULT_ATTRIBUTE}.
29+
* A sub-class of {@code DispatcherServlet} that saves the result in an
30+
* {@link MvcResult}. The {@code MvcResult} instance is expected to be available
31+
* as the request attribute {@link MockMvc#MVC_RESULT_ATTRIBUTE}.
3232
*
3333
* @author Rossen Stoyanchev
3434
* @author Rob Winch
3535
*/
3636
@SuppressWarnings("serial")
37-
public final class TestDispatcherServlet extends DispatcherServlet {
37+
final class TestDispatcherServlet extends DispatcherServlet {
3838

3939
/**
40-
* Create a new TestDispatcherServlet with the given {@code WebApplicationContext}.
40+
* Create a new instance with the given web application context.
4141
*/
4242
public TestDispatcherServlet(WebApplicationContext webApplicationContext) {
4343
super(webApplicationContext);
@@ -59,7 +59,9 @@ protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Ex
5959
}
6060

6161
@Override
62-
protected void render(ModelAndView mv, HttpServletRequest request, HttpServletResponse response) throws Exception {
62+
protected void render(ModelAndView mv, HttpServletRequest request, HttpServletResponse response)
63+
throws Exception {
64+
6365
DefaultMvcResult mvcResult = getMvcResult(request);
6466
mvcResult.setModelAndView(mv);
6567
super.render(mv, request, response);

0 commit comments

Comments
 (0)