20
20
21
21
import org .apache .commons .logging .Log ;
22
22
import org .apache .commons .logging .LogFactory ;
23
-
24
23
import org .springframework .beans .factory .config .ConfigurableListableBeanFactory ;
25
24
import org .springframework .context .ApplicationContext ;
26
25
import org .springframework .context .ConfigurableApplicationContext ;
@@ -74,6 +73,16 @@ public class ServletTestExecutionListener extends AbstractTestExecutionListener
74
73
public static final String RESET_REQUEST_CONTEXT_HOLDER_ATTRIBUTE = Conventions .getQualifiedAttributeName (
75
74
ServletTestExecutionListener .class , "resetRequestContextHolder" );
76
75
76
+ /**
77
+ * Attribute name for a {@link TestContext} attribute which indicates that
78
+ * {@code ServletTestExecutionListener} has already populated Spring Web's
79
+ * {@code RequestContextHolder}.
80
+ *
81
+ * <p>Permissible values include {@link Boolean#TRUE} and {@link Boolean#FALSE}.
82
+ */
83
+ public static final String POPULATED_REQUEST_CONTEXT_HOLDER_ATTRIBUTE = Conventions .getQualifiedAttributeName (
84
+ ServletTestExecutionListener .class , "populatedRequestContextHolder" );
85
+
77
86
private static final Log logger = LogFactory .getLog (ServletTestExecutionListener .class );
78
87
79
88
@@ -111,8 +120,10 @@ public void beforeTestMethod(TestContext testContext) throws Exception {
111
120
* {@code RequestContextHolder}, but only if the {@link
112
121
* #RESET_REQUEST_CONTEXT_HOLDER_ATTRIBUTE} in the supplied {@code TestContext}
113
122
* 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.
123
+ *
124
+ * <p>The {@link #RESET_REQUEST_CONTEXT_HOLDER_ATTRIBUTE} and
125
+ * {@link #POPULATED_REQUEST_CONTEXT_HOLDER_ATTRIBUTE} will be subsequently
126
+ * removed from the test context, regardless of their values.
116
127
*
117
128
* @see TestExecutionListener#afterTestMethod(TestContext)
118
129
*/
@@ -123,15 +134,20 @@ public void afterTestMethod(TestContext testContext) throws Exception {
123
134
}
124
135
RequestContextHolder .resetRequestAttributes ();
125
136
}
137
+ testContext .removeAttribute (POPULATED_REQUEST_CONTEXT_HOLDER_ATTRIBUTE );
126
138
testContext .removeAttribute (RESET_REQUEST_CONTEXT_HOLDER_ATTRIBUTE );
127
139
}
128
140
129
141
private boolean notAnnotatedWithWebAppConfiguration (TestContext testContext ) {
130
142
return AnnotationUtils .findAnnotation (testContext .getTestClass (), WebAppConfiguration .class ) == null ;
131
143
}
132
144
145
+ private boolean alreadyPopulatedRequestContextHolder (TestContext testContext ) {
146
+ return Boolean .TRUE .equals (testContext .getAttribute (POPULATED_REQUEST_CONTEXT_HOLDER_ATTRIBUTE ));
147
+ }
148
+
133
149
private void setUpRequestContextIfNecessary (TestContext testContext ) {
134
- if (notAnnotatedWithWebAppConfiguration (testContext )) {
150
+ if (notAnnotatedWithWebAppConfiguration (testContext ) || alreadyPopulatedRequestContextHolder ( testContext ) ) {
135
151
return ;
136
152
}
137
153
@@ -156,6 +172,7 @@ private void setUpRequestContextIfNecessary(TestContext testContext) {
156
172
ServletWebRequest servletWebRequest = new ServletWebRequest (request , response );
157
173
158
174
RequestContextHolder .setRequestAttributes (servletWebRequest );
175
+ testContext .setAttribute (POPULATED_REQUEST_CONTEXT_HOLDER_ATTRIBUTE , Boolean .TRUE );
159
176
testContext .setAttribute (RESET_REQUEST_CONTEXT_HOLDER_ATTRIBUTE , Boolean .TRUE );
160
177
161
178
if (wac instanceof ConfigurableApplicationContext ) {
0 commit comments