对于最新稳定版本,请使用 Spring Framework 7.0.6spring-doc.cadn.net.cn

@DirtiesContext

@DirtiesContext 表示在测试执行期间,底层的 Spring ApplicationContext 已被污染(即测试以某种方式修改或破坏了该上下文——例如,更改了单例 bean 的状态),应当将其关闭。当一个应用上下文被标记为已污染时,它会从测试框架的缓存中移除并关闭。因此,对于后续任何需要具有相同配置元数据的上下文的测试,底层的 Spring 容器都会被重新构建。spring-doc.cadn.net.cn

你可以在同一个类或类层次结构中,同时将 @DirtiesContext 用作类级别和方法级别的注解。在这种情况下,ApplicationContext 会根据所配置的 methodModeclassMode,在任何此类带注解的方法之前或之后,以及在当前测试类之前或之后被标记为“脏”(dirty)。当 @DirtiesContext 同时在类级别和方法级别声明时,两个注解中配置的模式都会生效。例如,如果类模式设置为 BEFORE_EACH_TEST_METHOD,而方法模式设置为 AFTER_METHOD,那么上下文将在指定测试方法执行前后都被标记为“脏”。spring-doc.cadn.net.cn

以下示例说明了在各种配置场景下,上下文何时会被标记为脏(dirty):spring-doc.cadn.net.cn

  • 在当前测试类之前,当在类上声明且类模式设置为 BEFORE_CLASS 时。spring-doc.cadn.net.cn

    @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(即默认的类模式)时。spring-doc.cadn.net.cn

    @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. 时。spring-doc.cadn.net.cn

    @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. 时。spring-doc.cadn.net.cn

    @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 时。spring-doc.cadn.net.cn

    @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(即默认的方法模式)时。spring-doc.cadn.net.cn

    @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 实例都会从上下文缓存中移除并关闭。如果对于特定用例而言,这种彻底的算法显得过于冗余,你可以指定更简单的“仅当前层级”算法,如下例所示。spring-doc.cadn.net.cn

@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。spring-doc.cadn.net.cn