Servlet mocks are not reinjected into test instance between TestNG test methods [SPR-11626] #16249
Closed
1 task done
Labels
in: test
Issues in the test module
status: backported
An issue that has been backported to maintenance branches
type: bug
A general bug
Milestone
Sam Brannen opened SPR-11626 and commented
Status Quo
When executing TestNG-based integration tests that subclass
AbstractTestNGSpringContextTests
and are annotated with@WebAppConfiguration
, if theServletTestExecutionListener
resets the request attributes stored in theRequestContextHolder
after a test method, then any injected Servlet API mocks that are managed by the listener (e.g.,MockHttpServletRequest
,MockHttpServletResponse
, andServletWebRequest
) will continue to hold values from the first such test method.The net effect is that subsequent web tests will not have access to the current mocks.
See the referenced discussion on Stack Overflow for an example of a failing test case.
Analysis
The reason for this behavior is that
ServletTestExecutionListener
resets the request attributes after each test method, butDependencyInjectionTestExecutionListener
does not re-inject dependencies before each test method (at least not by default). When a second test method is executed, an injectedServletRequest
field will still reference theMockHttpServletRequest
that was created for the previous test method; whereas,ServletTestExecutionListener
creates a new instance ofMockHttpServletRequest
for each test method and sets it in the request attributes. Thus, the injected request and the one stored in theRequestContextHolder
are only the same for the first test method that executes in TestNG.Note: this bug only applies to TestNG tests; JUnit-based tests are not affected by this.
Temporary Work-Arounds
If you need a work-around before this fix is available, you have two options.
You can annotate the affected test methods with
@DirtiesContext
(or annotate your test class with@DirtiesContext(classMode = ClassMode.AFTER_EACH_TEST_METHOD))
. This will allow your tests to pass as you expect. The use of@DirtiesContext
will make Spring close your testApplicationContext
after each test method, and this will likely have a negative impact on the speed of your tests; however, as of Spring 3.2.8 and 4.0.3, this is the only non-custom solution.The second option is a more efficient work-around. Just define this custom
TestExecutionListener
in your project:And then annotate your test class like this:
That should clear up any issues and keep your test suite running quickly.
Deliverables
ServletTestExecutionListener
are re-injected into test instances between TestNG methods, if theRequestContextHolder
is reset.Affects: 3.2 GA
Reference URL: http://stackoverflow.com/questions/22712325/multiple-tests-with-autowired-mockhttpservletrequest-not-working
Issue Links:
Backported to: 3.2.9
The text was updated successfully, but these errors were encountered: