diff --git a/spring-test/src/main/java/org/springframework/test/context/web/ServletTestExecutionListener.java b/spring-test/src/main/java/org/springframework/test/context/web/ServletTestExecutionListener.java index 8f3fc809f8f..a5574d9fe38 100644 --- a/spring-test/src/main/java/org/springframework/test/context/web/ServletTestExecutionListener.java +++ b/spring-test/src/main/java/org/springframework/test/context/web/ServletTestExecutionListener.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2014 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -31,6 +31,7 @@ import org.springframework.mock.web.MockServletContext; import org.springframework.test.context.TestContext; import org.springframework.test.context.TestExecutionListener; import org.springframework.test.context.support.AbstractTestExecutionListener; +import org.springframework.test.context.support.DependencyInjectionTestExecutionListener; import org.springframework.util.Assert; import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.request.RequestContextHolder; @@ -115,11 +116,14 @@ public class ServletTestExecutionListener extends AbstractTestExecutionListener } /** - * Cleans up thread-local state after each test method by {@linkplain + * If the {@link #RESET_REQUEST_CONTEXT_HOLDER_ATTRIBUTE} in the supplied + * {@code TestContext} has a value of {@link Boolean#TRUE}, this method will + * (1) clean up thread-local state after each test method by {@linkplain * RequestContextHolder#resetRequestAttributes() resetting} Spring Web's - * {@code RequestContextHolder}, but only if the {@link - * #RESET_REQUEST_CONTEXT_HOLDER_ATTRIBUTE} in the supplied {@code TestContext} - * has a value of {@link Boolean#TRUE}. + * {@code RequestContextHolder} and (2) ensure that new mocks are injected + * into the test instance for subsequent tests by setting the + * {@link DependencyInjectionTestExecutionListener#REINJECT_DEPENDENCIES_ATTRIBUTE} + * in the test context to {@code true}. * *
The {@link #RESET_REQUEST_CONTEXT_HOLDER_ATTRIBUTE} and * {@link #POPULATED_REQUEST_CONTEXT_HOLDER_ATTRIBUTE} will be subsequently @@ -134,6 +138,8 @@ public class ServletTestExecutionListener extends AbstractTestExecutionListener logger.debug(String.format("Resetting RequestContextHolder for test context %s.", testContext)); } RequestContextHolder.resetRequestAttributes(); + testContext.setAttribute(DependencyInjectionTestExecutionListener.REINJECT_DEPENDENCIES_ATTRIBUTE, + Boolean.TRUE); } testContext.removeAttribute(POPULATED_REQUEST_CONTEXT_HOLDER_ATTRIBUTE); testContext.removeAttribute(RESET_REQUEST_CONTEXT_HOLDER_ATTRIBUTE); diff --git a/spring-test/src/test/java/org/springframework/test/context/testng/web/ServletTestExecutionListenerTestNGIntegrationTests.java b/spring-test/src/test/java/org/springframework/test/context/testng/web/ServletTestExecutionListenerTestNGIntegrationTests.java new file mode 100644 index 00000000000..55aa29e75ec --- /dev/null +++ b/spring-test/src/test/java/org/springframework/test/context/testng/web/ServletTestExecutionListenerTestNGIntegrationTests.java @@ -0,0 +1,78 @@ +/* + * Copyright 2002-2014 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.test.context.testng.web; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.testng.AbstractTestNGSpringContextTests; +import org.springframework.test.context.web.ServletTestExecutionListener; +import org.springframework.test.context.web.WebAppConfiguration; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; +import org.testng.annotations.Test; + +import static org.junit.Assert.*; + +/** + * TestNG-based integration tests for {@link ServletTestExecutionListener}. + * + * @author Sam Brannen + * @since 3.2.9 + * @see org.springframework.test.context.web.ServletTestExecutionListenerJUnitIntegrationTests + */ +@ContextConfiguration +@WebAppConfiguration +public class ServletTestExecutionListenerTestNGIntegrationTests extends AbstractTestNGSpringContextTests { + + @Configuration + static class Config { + /* no beans required for this test */ + } + + + @Autowired + private MockHttpServletRequest servletRequest; + + + /** + * Verifies bug fix for SPR-11626. + * + * @see #ensureMocksAreReinjectedBetweenTests_2 + */ + @Test + public void ensureMocksAreReinjectedBetweenTests_1() { + assertInjectedServletRequestEqualsRequestInRequestContextHolder(); + } + + /** + * Verifies bug fix for SPR-11626. + * + * @see #ensureMocksAreReinjectedBetweenTests_1 + */ + @Test + public void ensureMocksAreReinjectedBetweenTests_2() { + assertInjectedServletRequestEqualsRequestInRequestContextHolder(); + } + + private void assertInjectedServletRequestEqualsRequestInRequestContextHolder() { + assertEquals("Injected ServletRequest must be stored in the RequestContextHolder", servletRequest, + ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest()); + } + +} diff --git a/spring-test/src/test/java/org/springframework/test/context/web/ServletTestExecutionListenerJUnitIntegrationTests.java b/spring-test/src/test/java/org/springframework/test/context/web/ServletTestExecutionListenerJUnitIntegrationTests.java new file mode 100644 index 00000000000..f8dfa2c9558 --- /dev/null +++ b/spring-test/src/test/java/org/springframework/test/context/web/ServletTestExecutionListenerJUnitIntegrationTests.java @@ -0,0 +1,78 @@ +/* + * Copyright 2002-2014 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.test.context.web; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import static org.junit.Assert.*; + +/** + * JUnit-based integration tests for {@link ServletTestExecutionListener}. + * + * @author Sam Brannen + * @since 3.2.9 + * @see org.springframework.test.context.testng.web.ServletTestExecutionListenerTestNGIntegrationTests + */ +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration +@WebAppConfiguration +public class ServletTestExecutionListenerJUnitIntegrationTests { + + @Configuration + static class Config { + /* no beans required for this test */ + } + + + @Autowired + private MockHttpServletRequest servletRequest; + + + /** + * Verifies bug fix for SPR-11626. + * + * @see #ensureMocksAreReinjectedBetweenTests_2 + */ + @Test + public void ensureMocksAreReinjectedBetweenTests_1() { + assertInjectedServletRequestEqualsRequestInRequestContextHolder(); + } + + /** + * Verifies bug fix for SPR-11626. + * + * @see #ensureMocksAreReinjectedBetweenTests_1 + */ + @Test + public void ensureMocksAreReinjectedBetweenTests_2() { + assertInjectedServletRequestEqualsRequestInRequestContextHolder(); + } + + private void assertInjectedServletRequestEqualsRequestInRequestContextHolder() { + assertEquals("Injected ServletRequest must be stored in the RequestContextHolder", servletRequest, + ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest()); + } + +}