Do not repopulate RequestContextHolder in ServTEL
This commit fixes a bug introduced in the last commit.
ServletTestExecutionListener (STEL) now tracks whether it has already
populated the RequestContextHolder.
Issue: SPR-11144
Backport-Commit: 800018a817
This commit is contained in:
parent
6ded287144
commit
38ad39f467
|
|
@ -20,7 +20,6 @@ import javax.servlet.ServletContext;
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||||
import org.springframework.context.ApplicationContext;
|
import org.springframework.context.ApplicationContext;
|
||||||
import org.springframework.context.ConfigurableApplicationContext;
|
import org.springframework.context.ConfigurableApplicationContext;
|
||||||
|
|
@ -74,6 +73,16 @@ public class ServletTestExecutionListener extends AbstractTestExecutionListener
|
||||||
public static final String RESET_REQUEST_CONTEXT_HOLDER_ATTRIBUTE = Conventions.getQualifiedAttributeName(
|
public static final String RESET_REQUEST_CONTEXT_HOLDER_ATTRIBUTE = Conventions.getQualifiedAttributeName(
|
||||||
ServletTestExecutionListener.class, "resetRequestContextHolder");
|
ServletTestExecutionListener.class, "resetRequestContextHolder");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attribute name for a {@link TestContext} attribute which indicates that
|
||||||
|
* {@code ServletTestExecutionListener} has already populated Spring Web's
|
||||||
|
* {@code RequestContextHolder}.
|
||||||
|
*
|
||||||
|
* <p>Permissible values include {@link Boolean#TRUE} and {@link Boolean#FALSE}.
|
||||||
|
*/
|
||||||
|
public static final String POPULATED_REQUEST_CONTEXT_HOLDER_ATTRIBUTE = Conventions.getQualifiedAttributeName(
|
||||||
|
ServletTestExecutionListener.class, "populatedRequestContextHolder");
|
||||||
|
|
||||||
private static final Log logger = LogFactory.getLog(ServletTestExecutionListener.class);
|
private static final Log logger = LogFactory.getLog(ServletTestExecutionListener.class);
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -111,8 +120,10 @@ public class ServletTestExecutionListener extends AbstractTestExecutionListener
|
||||||
* {@code RequestContextHolder}, but only if the {@link
|
* {@code RequestContextHolder}, but only if the {@link
|
||||||
* #RESET_REQUEST_CONTEXT_HOLDER_ATTRIBUTE} in the supplied {@code TestContext}
|
* #RESET_REQUEST_CONTEXT_HOLDER_ATTRIBUTE} in the supplied {@code TestContext}
|
||||||
* has a value of {@link Boolean#TRUE}.
|
* has a value of {@link Boolean#TRUE}.
|
||||||
* <p>The {@link #RESET_REQUEST_CONTEXT_HOLDER_ATTRIBUTE} will be
|
*
|
||||||
* subsequently removed from the test context, regardless of its value.
|
* <p>The {@link #RESET_REQUEST_CONTEXT_HOLDER_ATTRIBUTE} and
|
||||||
|
* {@link #POPULATED_REQUEST_CONTEXT_HOLDER_ATTRIBUTE} will be subsequently
|
||||||
|
* removed from the test context, regardless of their values.
|
||||||
*
|
*
|
||||||
* @see TestExecutionListener#afterTestMethod(TestContext)
|
* @see TestExecutionListener#afterTestMethod(TestContext)
|
||||||
*/
|
*/
|
||||||
|
|
@ -123,6 +134,7 @@ public class ServletTestExecutionListener extends AbstractTestExecutionListener
|
||||||
}
|
}
|
||||||
RequestContextHolder.resetRequestAttributes();
|
RequestContextHolder.resetRequestAttributes();
|
||||||
}
|
}
|
||||||
|
testContext.removeAttribute(POPULATED_REQUEST_CONTEXT_HOLDER_ATTRIBUTE);
|
||||||
testContext.removeAttribute(RESET_REQUEST_CONTEXT_HOLDER_ATTRIBUTE);
|
testContext.removeAttribute(RESET_REQUEST_CONTEXT_HOLDER_ATTRIBUTE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -130,8 +142,12 @@ public class ServletTestExecutionListener extends AbstractTestExecutionListener
|
||||||
return AnnotationUtils.findAnnotation(testContext.getTestClass(), WebAppConfiguration.class) == null;
|
return AnnotationUtils.findAnnotation(testContext.getTestClass(), WebAppConfiguration.class) == null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean alreadyPopulatedRequestContextHolder(TestContext testContext) {
|
||||||
|
return Boolean.TRUE.equals(testContext.getAttribute(POPULATED_REQUEST_CONTEXT_HOLDER_ATTRIBUTE));
|
||||||
|
}
|
||||||
|
|
||||||
private void setUpRequestContextIfNecessary(TestContext testContext) {
|
private void setUpRequestContextIfNecessary(TestContext testContext) {
|
||||||
if (notAnnotatedWithWebAppConfiguration(testContext)) {
|
if (notAnnotatedWithWebAppConfiguration(testContext) || alreadyPopulatedRequestContextHolder(testContext)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -156,6 +172,7 @@ public class ServletTestExecutionListener extends AbstractTestExecutionListener
|
||||||
ServletWebRequest servletWebRequest = new ServletWebRequest(request, response);
|
ServletWebRequest servletWebRequest = new ServletWebRequest(request, response);
|
||||||
|
|
||||||
RequestContextHolder.setRequestAttributes(servletWebRequest);
|
RequestContextHolder.setRequestAttributes(servletWebRequest);
|
||||||
|
testContext.setAttribute(POPULATED_REQUEST_CONTEXT_HOLDER_ATTRIBUTE, Boolean.TRUE);
|
||||||
testContext.setAttribute(RESET_REQUEST_CONTEXT_HOLDER_ATTRIBUTE, Boolean.TRUE);
|
testContext.setAttribute(RESET_REQUEST_CONTEXT_HOLDER_ATTRIBUTE, Boolean.TRUE);
|
||||||
|
|
||||||
if (wac instanceof ConfigurableApplicationContext) {
|
if (wac instanceof ConfigurableApplicationContext) {
|
||||||
|
|
|
||||||
|
|
@ -175,14 +175,18 @@ public class ServletTestExecutionListenerTests {
|
||||||
private void assertWebAppConfigTestCase() throws Exception {
|
private void assertWebAppConfigTestCase() throws Exception {
|
||||||
listener.prepareTestInstance(testContext);
|
listener.prepareTestInstance(testContext);
|
||||||
assertAttributeDoesNotExist();
|
assertAttributeDoesNotExist();
|
||||||
|
verify(testContext, times(1)).setAttribute(POPULATED_REQUEST_CONTEXT_HOLDER_ATTRIBUTE, Boolean.TRUE);
|
||||||
verify(testContext, times(1)).setAttribute(RESET_REQUEST_CONTEXT_HOLDER_ATTRIBUTE, Boolean.TRUE);
|
verify(testContext, times(1)).setAttribute(RESET_REQUEST_CONTEXT_HOLDER_ATTRIBUTE, Boolean.TRUE);
|
||||||
|
when(testContext.getAttribute(POPULATED_REQUEST_CONTEXT_HOLDER_ATTRIBUTE)).thenReturn(Boolean.TRUE);
|
||||||
when(testContext.getAttribute(RESET_REQUEST_CONTEXT_HOLDER_ATTRIBUTE)).thenReturn(Boolean.TRUE);
|
when(testContext.getAttribute(RESET_REQUEST_CONTEXT_HOLDER_ATTRIBUTE)).thenReturn(Boolean.TRUE);
|
||||||
|
|
||||||
listener.beforeTestMethod(testContext);
|
listener.beforeTestMethod(testContext);
|
||||||
assertAttributeDoesNotExist();
|
assertAttributeDoesNotExist();
|
||||||
verify(testContext, times(2)).setAttribute(RESET_REQUEST_CONTEXT_HOLDER_ATTRIBUTE, Boolean.TRUE);
|
verify(testContext, times(1)).setAttribute(POPULATED_REQUEST_CONTEXT_HOLDER_ATTRIBUTE, Boolean.TRUE);
|
||||||
|
verify(testContext, times(1)).setAttribute(RESET_REQUEST_CONTEXT_HOLDER_ATTRIBUTE, Boolean.TRUE);
|
||||||
|
|
||||||
listener.afterTestMethod(testContext);
|
listener.afterTestMethod(testContext);
|
||||||
|
verify(testContext).removeAttribute(POPULATED_REQUEST_CONTEXT_HOLDER_ATTRIBUTE);
|
||||||
verify(testContext).removeAttribute(RESET_REQUEST_CONTEXT_HOLDER_ATTRIBUTE);
|
verify(testContext).removeAttribute(RESET_REQUEST_CONTEXT_HOLDER_ATTRIBUTE);
|
||||||
assertAttributesNotAvailable();
|
assertAttributesNotAvailable();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue