Ensure ServTEL doesn't reset ReqAttrs by accident
Prior to this commit, the ServletTestExecutionListener did not overwrite RequestAttributes in the RequestContextHolder if the ApplicationContext associated with the given TestContext was not a WebApplicationContext; however, the ServletTestExecutionListener would clear the RequestAttributes after every test method execution, regardless of whether the context was a WebApplicationContext or not. This behavior breaks backwards compatibility with integration tests that managed the RequestAttributes in RequestContextHolder themselves. This commit addresses this issue by introducing a TestContext attribute named RESET_REQUEST_CONTEXT_HOLDER_ATTRIBUTE in ServletTestExecutionListener. This attribute is used internally within ServletTestExecutionListener to ensure that the RequestContextHolder is only cleared (i.e., reset) if the ServletTestExecutionListener actually populated the RequestContextHolder. Issue: SPR-11144
This commit is contained in:
@@ -24,6 +24,7 @@ import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.core.Conventions;
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.mock.web.MockHttpServletResponse;
|
||||
import org.springframework.mock.web.MockServletContext;
|
||||
@@ -59,6 +60,17 @@ import org.springframework.web.context.request.ServletWebRequest;
|
||||
*/
|
||||
public class ServletTestExecutionListener extends AbstractTestExecutionListener {
|
||||
|
||||
/**
|
||||
* Attribute name for a {@link TestContext} attribute which indicates
|
||||
* whether or not the {@code ServletTestExecutionListener} should {@linkplain
|
||||
* RequestContextHolder#resetRequestAttributes() reset} Spring Web's
|
||||
* {@code RequestContextHolder} in {@link #afterTestMethod(TestContext)}.
|
||||
*
|
||||
* <p>Permissible values include {@link Boolean#TRUE} and {@link Boolean#FALSE}.
|
||||
*/
|
||||
public static final String RESET_REQUEST_CONTEXT_HOLDER_ATTRIBUTE = Conventions.getQualifiedAttributeName(
|
||||
ServletTestExecutionListener.class, "resetRequestContextHolder");
|
||||
|
||||
private static final Log logger = LogFactory.getLog(ServletTestExecutionListener.class);
|
||||
|
||||
|
||||
@@ -95,10 +107,13 @@ public class ServletTestExecutionListener extends AbstractTestExecutionListener
|
||||
*/
|
||||
@Override
|
||||
public void afterTestMethod(TestContext testContext) throws Exception {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug(String.format("Resetting RequestContextHolder for test context %s.", testContext));
|
||||
if (Boolean.TRUE.equals(testContext.getAttribute(RESET_REQUEST_CONTEXT_HOLDER_ATTRIBUTE))) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug(String.format("Resetting RequestContextHolder for test context %s.", testContext));
|
||||
}
|
||||
RequestContextHolder.resetRequestAttributes();
|
||||
testContext.removeAttribute(RESET_REQUEST_CONTEXT_HOLDER_ATTRIBUTE);
|
||||
}
|
||||
RequestContextHolder.resetRequestAttributes();
|
||||
}
|
||||
|
||||
private void setUpRequestContextIfNecessary(TestContext testContext) {
|
||||
@@ -127,6 +142,7 @@ public class ServletTestExecutionListener extends AbstractTestExecutionListener
|
||||
ServletWebRequest servletWebRequest = new ServletWebRequest(request, response);
|
||||
|
||||
RequestContextHolder.setRequestAttributes(servletWebRequest);
|
||||
testContext.setAttribute(RESET_REQUEST_CONTEXT_HOLDER_ATTRIBUTE, Boolean.TRUE);
|
||||
|
||||
if (wac instanceof ConfigurableApplicationContext) {
|
||||
@SuppressWarnings("resource")
|
||||
|
||||
Reference in New Issue
Block a user