将jUnit超时与@DirtiesContext

时间:2015-08-06 13:37:46

标签: java junit spring-test

我有一个修改我的spring上下文的测试用例,可能会遇到无限循环。在测试用例之后,我想要一个干净的弹簧上下文,所以我使用了@DirtiesContext注释。在无限循环的情况下,我添加了一个jUnit超时。

@Test(timeout = 1000)
@DirtiesContext
public void testTimeout() {
    //test stuff
}

问题是如果测试进入超时,jUnit似乎以一种春天不再处理上下文重置的方式终止它。如果我在类级别添加@DirtiesContext,则行为相同。

还有另一种方法可以实现我想要做的事情吗?

2 个答案:

答案 0 :(得分:1)

我设法解决了我的问题。我将spring升级到4.2.0,大约持续了一周,它支持在方法之前清理上下文。

@Test(timeout = 1000)
@DirtiesContext(methodMode = MethodMode.BEFORE_METHOD)
public void testTimeout() {
    //test stuff
}

这样,测试仍会在超时后终止,但在下一个方法之前清除上下文。猜测这种方式我每个测试类都有一个不必要的上下文初始化,但它可以工作。

答案 1 :(得分:1)

要使用JUnit和 Spring TestContext Framework (TCF)配置超时,您有两个主要类别的选项:

  1. 抢先:如果您使用JUnit的Timeout规则或timeout的{​​{1}}属性,则您的测试和所有嵌套规则相关联< em>在 / 之后的方法,TCF回调等将在一个单独的线程中执行,如果超过超时,则先抢先中止。
  2. 非抢占式:如果您使用Spring的@Test注释与TCF,您的测试和所有嵌套规则, / <之前关联的 em>在方法之后,TCF回调等将在与测试运行器相同的线程中执行,并且测试只有在正常终止并且超出超时时才会失败。 / LI>

    @Timed规则和Timeout timeout属性都会导致@Test语句被引用;并且FailOnTimeout在一个单独的线程中执行链中的下一个语句,如果超过超时,则抢先终止该线程。因此,这两个基于JUnit的配置选项的行为自然是相同的:语句链的执行过早结束,而不会在回调之后给任何机会执行其任务。结果是Spring FailOnTimeout中的 afterTestMethod()回调在这种情况下从不被调用,因此上下文不会被弄脏

      

    还有另一种方法可以实现我想要做的事情吗?

    首先,使用Spring的DirtiesContextTestExecutionListener注释不是一个选项,因为它不会抢先中止在无限循环中运行的代码。

    您提到您使用Spring Framework 4.2中引入的@Timed功能发现了一种解决方法。那些可能在某些情况下工作,但这种解决方法充其量是脆弱的:在 这个<之前,使用这种解决方案在上下文中关闭并重新启动 / strong>特定方法;但是,如果有问题的代码在抢占超时之前修改了上下文,那么对于后续测试方法,您的Spring上下文将保持损坏。

    唯一真正的解决方案是确保您在执行 next 方法上使用@DirtiesContext(methodMode = BEFORE_METHOD) @DirtiesContext模式由于超时而被抢先中止的方法。但是......确切知道哪种方法是&#34; next&#34;方法可能是具有挑战性的部分......除非您使用JUnit的BEFORE_METHOD支持。

    此致

    Sam( Spring TestContext Framework的作者