@DirtiesContext

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

你可以在同一个测试类或测试类层级结构中将 @DirtiesContext 用作类级别和方法级别的注解。在这种情况下,根据配置的 methodModeclassModeApplicationContext 会在任何此类带注解的方法之前或之后,以及在当前测试类之前或之后被标记为“脏”。当 @DirtiesContext 在类级别和方法级别都声明时,两个注解配置的模式都会生效。例如,如果类模式设置为 BEFORE_EACH_TEST_METHOD,方法模式设置为 AFTER_METHOD,则上下文会在给定的测试方法之前和之后都被标记为“脏”。

以下示例解释了在各种配置场景下上下文何时会被“弄脏”

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

    • Java

    • Kotlin

    @DirtiesContext(classMode = BEFORE_CLASS) (1)
    class FreshContextTests {
    	// some tests that require a new Spring container
    }
    1 在当前测试类之前弄脏上下文。
    @DirtiesContext(classMode = BEFORE_CLASS) (1)
    class FreshContextTests {
    	// some tests that require a new Spring container
    }
    1 在当前测试类之前弄脏上下文。
  • 在当前测试类之后,当在类上声明并将类模式设置为 AFTER_CLASS 时(即默认类模式)。

    • Java

    • Kotlin

    @DirtiesContext (1)
    class ContextDirtyingTests {
    	// some tests that result in the Spring container being dirtied
    }
    1 在当前测试类之后弄脏上下文。
    @DirtiesContext (1)
    class ContextDirtyingTests {
    	// some tests that result in the Spring container being dirtied
    }
    1 在当前测试类之后弄脏上下文。
  • 在当前测试类中的每个测试方法之前,当在类上声明并将类模式设置为 BEFORE_EACH_TEST_METHOD. 时。

    • Java

    • Kotlin

    @DirtiesContext(classMode = BEFORE_EACH_TEST_METHOD) (1)
    class FreshContextTests {
    	// some tests that require a new Spring container
    }
    1 在每个测试方法之前弄脏上下文。
    @DirtiesContext(classMode = BEFORE_EACH_TEST_METHOD) (1)
    class FreshContextTests {
    	// some tests that require a new Spring container
    }
    1 在每个测试方法之前弄脏上下文。
  • 在当前测试类中的每个测试方法之后,当在类上声明并将类模式设置为 AFTER_EACH_TEST_METHOD. 时。

    • Java

    • Kotlin

    @DirtiesContext(classMode = AFTER_EACH_TEST_METHOD) (1)
    class ContextDirtyingTests {
    	// some tests that result in the Spring container being dirtied
    }
    1 在每个测试方法之后弄脏上下文。
    @DirtiesContext(classMode = AFTER_EACH_TEST_METHOD) (1)
    class ContextDirtyingTests {
    	// some tests that result in the Spring container being dirtied
    }
    1 在每个测试方法之后弄脏上下文。
  • 在当前测试方法之前,当在方法上声明并将方法模式设置为 BEFORE_METHOD 时。

    • Java

    • Kotlin

    @DirtiesContext(methodMode = BEFORE_METHOD) (1)
    @Test
    void testProcessWhichRequiresFreshAppCtx() {
    	// some logic that requires a new Spring container
    }
    1 在当前测试方法之前弄脏上下文。
    @DirtiesContext(methodMode = BEFORE_METHOD) (1)
    @Test
    fun testProcessWhichRequiresFreshAppCtx() {
    	// some logic that requires a new Spring container
    }
    1 在当前测试方法之前弄脏上下文。
  • 在当前测试方法之后,当在方法上声明并将方法模式设置为 AFTER_METHOD 时(即默认方法模式)。

    • Java

    • Kotlin

    @DirtiesContext (1)
    @Test
    void testProcessWhichDirtiesAppCtx() {
    	// some logic that results in the Spring container being dirtied
    }
    1 在当前测试方法之后弄脏上下文。
    @DirtiesContext (1)
    @Test
    fun testProcessWhichDirtiesAppCtx() {
    	// some logic that results in the Spring container being dirtied
    }
    1 在当前测试方法之后弄脏上下文。

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

  • Java

  • Kotlin

@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() {
		// some logic that results in the child context being dirtied
	}
}
1 使用当前层级算法。
@ContextHierarchy(
	ContextConfiguration("/parent-config.xml"),
	ContextConfiguration("/child-config.xml"))
open class BaseTests {
	// class body...
}

class ExtendedTests : BaseTests() {

	@Test
	@DirtiesContext(hierarchyMode = CURRENT_LEVEL) (1)
	fun test() {
		// some logic that results in the child context being dirtied
	}
}
1 使用当前层级算法。

关于 EXHAUSTIVECURRENT_LEVEL 算法的更多详细信息,请参阅 DirtiesContext.HierarchyMode 的 Javadoc。