我在一些Spring测试中使用@Autowired MockHttpServletRequest
。 TestNG用作测试框架。如果我在课堂上只有一个测试方法,这个工作正常。但是,如果有多个测试方法,则只有第一次运行测试使用我的MockHttpServletRequest。让我举一个例子来说明:
@WebAppConfiguration
@ContextConfiguration({"classpath:applicationContext.xml"})
public class FooTest extends AbstractTestNGSpringContextTests {
@Autowired
private MockHttpServletRequest servletRequest;
@Test
public void test1() {
assertEquals(((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest(), servletRequest);
}
@Test
public void test2() {
assertEquals(((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest(), servletRequest);
}
}
在此示例中,test1()
通过,但test2()
失败!如果单独运行测试方法,它们都会通过。如果一个测试一起运行,为什么一个测试会失败?
我试图挖掘代码,在测试方法运行后似乎有某种类型的请求属性重置,但我没有办法将其关闭。我的Spring版本是3.2.8.RELEASE。
答案 0 :(得分:4)
UPDATE :这已在Spring Framework 3.2.9,4.0.4和4.1中修复。有关详细信息,请参阅SPR-11626。
好吧,我的朋友......你在 Spring TestContext Framework 中发现了一个错误。
此行为的原因是ServletTestExecutionListener
在每个测试方法之后重置请求属性,但DependencyInjectionTestExecutionListener
在每个测试方法之前不会重新注入依赖项(默认情况下)。执行第二个测试方法时,servletRequest
字段仍然引用为先前测试方法创建的MockHttpServletRequest
;而ServletTestExecutionListener
为每个测试方法创建一个MockHttpServletRequest
的新实例,并将其设置在请求属性中。因此,注入的请求和RequestContextHolder
中存储的请求仅与在TestNG中执行的第一个测试方法相同。
由于我是此代码的作者,我必须亲自道歉,但是......我确保尽快修复它。有关修复程序状态的详细信息,请参阅SPR-11626。 ;)
注意:此错误仅适用于TestNG测试;这 not 适用于JUnit测试。
作为解决方法,您可以使用@DirtiesContext
注释受影响的测试方法(或使用@DirtiesContext(classMode = ClassMode.AFTER_EACH_TEST_METHOD)
注释您的测试类)。这将允许您的测试按预期通过。
使用@DirtiesContext
会使Spring在每个测试方法后关闭您的测试ApplicationContext
,这可能会对测试的速度产生负面影响;但是,从Spring 3.2.8和4.0.3开始,这是唯一的非自定义解决方案。
话虽如此,以下是一种更有效的解决方法。只需在项目中定义此自定义TestExecutionListener
:
public class AlwaysReinjectDependenciesTestExecutionListener extends AbstractTestExecutionListener {
public void afterTestMethod(TestContext testContext) throws Exception {
testContext.setAttribute(DependencyInjectionTestExecutionListener.REINJECT_DEPENDENCIES_ATTRIBUTE, Boolean.TRUE);
}
}
然后像这样注释你的测试类:
@TestExecutionListeners(AlwaysReinjectDependenciesTestExecutionListener.class)
这应该清除任何问题和让您的测试套件快速运行。
此致
萨姆