@DirtiesContext

@DirtiesContext 指示底层的 Infra ApplicationContext 在测试执行期间已被弄脏(即,测试以某种方式修改或破坏了它——例如,通过更改单例 bean 的状态),应该关闭。当应用程序上下文被标记为脏时,它将从测试框架的缓存中移除并关闭。因此,对于任何后续需要具有相同配置元数据的上下文的测试,底层 Infra 容器将被重建。

你可以在同一个类或类层次结构中将 @DirtiesContext 同时用作类级别和方法级别的注解。在这种情况下,ApplicationContext 会在任何此类注解方法之前或之后,以及在当前测试类之前或之后被标记为脏,具体取决于配置的 methodModeclassMode。当在类级别和方法级别都声明 @DirtiesContext 时,两个注解的配置模式都将被遵守。例如,如果类模式设置为 BEFORE_EACH_TEST_METHOD,而方法模式设置为 AFTER_METHOD,则上下文将在给定的测试方法之前和之后都被标记为脏。

以下示例解释了在各种配置场景下上下文何时会被标记为脏:

  • 在当前测试类之前,当在类模式设置为 BEFORE_CLASS 的类上声明时。

    • Java

    @DirtiesContext(classMode = BEFORE_CLASS) (1)
    class FreshContextTests {
      // 一些需要新 Infra 容器的测试
    }
    1 在当前测试类之前将上下文标记为脏。
  • 在当前测试类之后,当在类模式设置为 AFTER_CLASS(即默认类模式)的类上声明时。

    • Java

    @DirtiesContext (1)
    class ContextDirtyingTests {
    	// 一些导致 Infra 容器被弄脏的测试
    }
    1 在当前测试类之后将上下文标记为脏。
  • 在当前测试类中的每个测试方法之前,当在类模式设置为 BEFORE_EACH_TEST_METHOD 的类上声明时。

    • Java

    @DirtiesContext(classMode = BEFORE_EACH_TEST_METHOD) (1)
    class FreshContextTests {
      // 一些需要新 Infra 容器的测试
    }
    1 在每个测试方法之前将上下文标记为脏。
  • 在当前测试类中的每个测试方法之后,当在类模式设置为 AFTER_EACH_TEST_METHOD 的类上声明时。

    • Java

    @DirtiesContext(classMode = AFTER_EACH_TEST_METHOD) (1)
    class ContextDirtyingTests {
      // 一些导致 Infra 容器被弄脏的测试
    }
    1 在每个测试方法之后将上下文标记为脏。
  • 在当前测试之前,当在方法模式设置为 BEFORE_METHOD 的方法上声明时。

    • Java

    @DirtiesContext(methodMode = BEFORE_METHOD) (1)
    @Test
    void testProcessWhichRequiresFreshAppCtx() {
      // 一些需要新 Infra 容器的逻辑
    }
    1 在当前测试方法之前将上下文标记为脏。
  • 在当前测试之后,当在方法模式设置为 AFTER_METHOD(即默认方法模式)的方法上声明时。

    • Java

    @DirtiesContext (1)
    @Test
    void testProcessWhichDirtiesAppCtx() {
      // 一些导致 Infra 容器被弄脏的逻辑
    }
    1 在当前测试方法之后将上下文标记为脏。

如果你在上下文配置为具有 @ContextHierarchy 的上下文层次结构一部分的测试中使用 @DirtiesContext,你可以使用 hierarchyMode 标志来控制如何清除上下文缓存。默认情况下,使用详尽算法清除上下文缓存,不仅包括当前层级,还包括共享当前测试公共祖先上下文的所有其他上下文层次结构。位于公共祖先上下文子层次结构中的所有 ApplicationContext 实例都将从上下文缓存中移除并关闭。如果详尽算法对于特定用例来说是过度杀伤,你可以指定更简单的当前层级算法,如下例所示。

  • Java

@ContextHierarchy({
  @ContextConfiguration("/parent-config.xml"),
  @ContextConfiguration("/child-config.xml")
})
class BaseTests {
  // class body...
}

class ExtendedTests extends BaseTests {

  @Test
  @DirtiesContext(hierarchyMode = CURRENT_LEVEL) (1)
  void test() {
    // 一些导致子上下文被弄脏的逻辑
  }
}
1 使用当前层级算法。

有关 EXHAUSTIVECURRENT_LEVEL 算法的更多详细信息,请参见 DirtiesContext.HierarchyMode javadoc。