25
25
import org .springframework .context .ApplicationContext ;
26
26
import org .springframework .context .ConfigurableApplicationContext ;
27
27
import org .springframework .core .Conventions ;
28
+ import org .springframework .core .annotation .AnnotationUtils ;
28
29
import org .springframework .mock .web .MockHttpServletRequest ;
29
30
import org .springframework .mock .web .MockHttpServletResponse ;
30
31
import org .springframework .mock .web .MockServletContext ;
31
32
import org .springframework .test .context .TestContext ;
32
33
import org .springframework .test .context .TestExecutionListener ;
33
34
import org .springframework .test .context .support .AbstractTestExecutionListener ;
35
+ import org .springframework .util .Assert ;
34
36
import org .springframework .web .context .WebApplicationContext ;
35
37
import org .springframework .web .context .request .RequestContextHolder ;
36
38
import org .springframework .web .context .request .ServletWebRequest ;
52
54
* #afterTestMethod(TestContext) cleans up} thread-local state.
53
55
*
54
56
* <p>Note that {@code ServletTestExecutionListener} is enabled by default but
55
- * takes no action if the {@link ApplicationContext} loaded for the current test
56
- * is not a {@link WebApplicationContext}.
57
+ * generally takes no action if the {@linkplain TestContext#getTestClass() test
58
+ * class} is not annotated with {@link WebAppConfiguration @WebAppConfiguration}.
59
+ * See the Javadoc for individual methods in this class for details.
57
60
*
58
61
* @author Sam Brannen
59
62
* @since 3.2
@@ -76,7 +79,9 @@ public class ServletTestExecutionListener extends AbstractTestExecutionListener
76
79
77
80
/**
78
81
* Sets up thread-local state during the <em>test instance preparation</em>
79
- * callback phase via Spring Web's {@link RequestContextHolder}.
82
+ * callback phase via Spring Web's {@link RequestContextHolder}, but only if
83
+ * the {@linkplain TestContext#getTestClass() test class} is annotated with
84
+ * {@link WebAppConfiguration @WebAppConfiguration}.
80
85
*
81
86
* @see TestExecutionListener#prepareTestInstance(TestContext)
82
87
* @see #setUpRequestContextIfNecessary(TestContext)
@@ -88,7 +93,9 @@ public void prepareTestInstance(TestContext testContext) throws Exception {
88
93
89
94
/**
90
95
* Sets up thread-local state before each test method via Spring Web's
91
- * {@link RequestContextHolder}.
96
+ * {@link RequestContextHolder}, but only if the
97
+ * {@linkplain TestContext#getTestClass() test class} is annotated with
98
+ * {@link WebAppConfiguration @WebAppConfiguration}.
92
99
*
93
100
* @see TestExecutionListener#beforeTestMethod(TestContext)
94
101
* @see #setUpRequestContextIfNecessary(TestContext)
@@ -101,7 +108,11 @@ public void beforeTestMethod(TestContext testContext) throws Exception {
101
108
/**
102
109
* Cleans up thread-local state after each test method by {@linkplain
103
110
* RequestContextHolder#resetRequestAttributes() resetting} Spring Web's
104
- * {@code RequestContextHolder}.
111
+ * {@code RequestContextHolder}, but only if the {@link
112
+ * #RESET_REQUEST_CONTEXT_HOLDER_ATTRIBUTE} in the supplied {@code TestContext}
113
+ * has a value of {@link Boolean#TRUE}.
114
+ * <p>The {@link #RESET_REQUEST_CONTEXT_HOLDER_ATTRIBUTE} will be
115
+ * subsequently removed from the test context, regardless of its value.
105
116
*
106
117
* @see TestExecutionListener#afterTestMethod(TestContext)
107
118
*/
@@ -111,45 +122,48 @@ public void afterTestMethod(TestContext testContext) throws Exception {
111
122
logger .debug (String .format ("Resetting RequestContextHolder for test context %s." , testContext ));
112
123
}
113
124
RequestContextHolder .resetRequestAttributes ();
114
- testContext .removeAttribute (RESET_REQUEST_CONTEXT_HOLDER_ATTRIBUTE );
115
125
}
126
+ testContext .removeAttribute (RESET_REQUEST_CONTEXT_HOLDER_ATTRIBUTE );
127
+ }
128
+
129
+ private boolean notAnnotatedWithWebAppConfiguration (TestContext testContext ) {
130
+ return AnnotationUtils .findAnnotation (testContext .getTestClass (), WebAppConfiguration .class ) == null ;
116
131
}
117
132
118
133
private void setUpRequestContextIfNecessary (TestContext testContext ) {
134
+ if (notAnnotatedWithWebAppConfiguration (testContext )) {
135
+ return ;
136
+ }
119
137
120
138
ApplicationContext context = testContext .getApplicationContext ();
121
139
122
140
if (context instanceof WebApplicationContext ) {
123
141
WebApplicationContext wac = (WebApplicationContext ) context ;
124
142
ServletContext servletContext = wac .getServletContext ();
125
- if (!(servletContext instanceof MockServletContext )) {
126
- throw new IllegalStateException (String .format (
127
- "The WebApplicationContext for test context %s must be configured with a MockServletContext." ,
128
- testContext ));
129
- }
143
+ Assert .state (servletContext instanceof MockServletContext , String .format (
144
+ "The WebApplicationContext for test context %s must be configured with a MockServletContext." ,
145
+ testContext ));
130
146
131
147
if (logger .isDebugEnabled ()) {
132
148
logger .debug (String .format (
133
149
"Setting up MockHttpServletRequest, MockHttpServletResponse, ServletWebRequest, and RequestContextHolder for test context %s." ,
134
150
testContext ));
135
151
}
136
152
137
- if (RequestContextHolder .getRequestAttributes () == null ) {
138
- MockServletContext mockServletContext = (MockServletContext ) servletContext ;
139
- MockHttpServletRequest request = new MockHttpServletRequest (mockServletContext );
140
- MockHttpServletResponse response = new MockHttpServletResponse ();
141
- ServletWebRequest servletWebRequest = new ServletWebRequest (request , response );
142
-
143
- RequestContextHolder .setRequestAttributes (servletWebRequest );
144
- testContext .setAttribute (RESET_REQUEST_CONTEXT_HOLDER_ATTRIBUTE , Boolean .TRUE );
145
-
146
- if (wac instanceof ConfigurableApplicationContext ) {
147
- @ SuppressWarnings ("resource" )
148
- ConfigurableApplicationContext configurableApplicationContext = (ConfigurableApplicationContext ) wac ;
149
- ConfigurableListableBeanFactory bf = configurableApplicationContext .getBeanFactory ();
150
- bf .registerResolvableDependency (MockHttpServletResponse .class , response );
151
- bf .registerResolvableDependency (ServletWebRequest .class , servletWebRequest );
152
- }
153
+ MockServletContext mockServletContext = (MockServletContext ) servletContext ;
154
+ MockHttpServletRequest request = new MockHttpServletRequest (mockServletContext );
155
+ MockHttpServletResponse response = new MockHttpServletResponse ();
156
+ ServletWebRequest servletWebRequest = new ServletWebRequest (request , response );
157
+
158
+ RequestContextHolder .setRequestAttributes (servletWebRequest );
159
+ testContext .setAttribute (RESET_REQUEST_CONTEXT_HOLDER_ATTRIBUTE , Boolean .TRUE );
160
+
161
+ if (wac instanceof ConfigurableApplicationContext ) {
162
+ @ SuppressWarnings ("resource" )
163
+ ConfigurableApplicationContext configurableApplicationContext = (ConfigurableApplicationContext ) wac ;
164
+ ConfigurableListableBeanFactory bf = configurableApplicationContext .getBeanFactory ();
165
+ bf .registerResolvableDependency (MockHttpServletResponse .class , response );
166
+ bf .registerResolvableDependency (ServletWebRequest .class , servletWebRequest );
153
167
}
154
168
}
155
169
}
0 commit comments