The combination of loading a WebApplicationContext with the Spring TestContext Framework (TCF) and using the Spring MVC Test Framework results in two instances of MockHttpServletRequest being created. See #17803 for additional information.
The fact that two mocked requests are created can lead to a subtle bug if a Servlet Filter (or a Spring-managed component invoked by a filter) attempts to access the RequestAttributes before the TestDispatcherServlet is invoked by MockMvc. Specifically, the filter (or its collaborator) will work with the mocked request created by the ServletTestExecutionListener; whereas, the controller that is invoked by MockMvc will work with the mocked request managed by MockMvc. Consequently, if the controller expects the filter to store information in the request (e.g., request attributes), the test will fail.
In production deployments the aforementioned bug will not occur if the RequestContextFilter or RequestContextListener is configured for the web application. When using MockMvc with the TCF, however, it is necessary to manually add a RequestContextFilter to MockMvcbefore any such custom filters -- for example:
Populate RequestAttributes before invoking Filters in MockMvc
When using the Spring TestContext Framework (TCF) to load a WebApplicationContext and the Spring MVC Test Framework (MockMvc) to test a controller, two instances of MockHttpServletRequest will be created. Due to an ordering issue with regard to population of the RequestAttributes, it is therefore possible that a filter accesses the mocked request managed by the TCF, while the controller accesses the mocked request managed by MockMvc, and this leads to test failures if the controller expects data from the filter to be present in the request.
This commit fixes this bug by ensuring that the RequestAttributes backed by the mocked request managed by MockMvc are stored in the RequestContextHolder before any filters are invoked by MockMvc.