You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在测试类上使用@DirtiesContext注解的具体含义及示例

关于Spring @DirtiesContext标注在测试类上的含义及示例

嘿,这个问题问到点子上了!很多人刚接触这个注解时都会混淆方法级和类级的用法,我来给你掰扯明白~

首先得明确:@DirtiesContext的核心作用是标记Spring应用上下文为“脏”(也就是上下文里的Bean状态被修改过,不再干净),让Spring在合适的时机销毁并重新创建上下文。当你把它标注在测试类上时,具体行为由mode参数决定,默认是Mode.AFTER_CLASS,下面分情况细说:

1. 默认行为:Mode.AFTER_CLASS

如果直接在测试类上标注@DirtiesContext不指定mode,意味着:

整个测试类的所有测试方法执行完成后,才会将上下文标记为脏并销毁。后续如果有其他测试需要使用上下文,会重新创建一个全新的。

这种场景适合:测试类里的所有方法可以共享同一个上下文,且方法执行完的状态不会影响其他测试类的情况。

示例代码:

@SpringBootTest
@DirtiesContext // 默认Mode.AFTER_CLASS
public class UserServiceTest {

    @Autowired
    private UserService userService;

    @Test
    void testCreateUser() {
        userService.createUser("Alice");
        assertEquals(1, userService.getUserCount());
    }

    @Test
    void testDeleteUser() {
        // 这里的userService是和上一个方法共享的,所以初始计数是1
        userService.deleteUser("Alice");
        assertEquals(0, userService.getUserCount());
    }
}

2. Mode.BEFORE_CLASS

当你指定mode = DirtiesContext.Mode.BEFORE_CLASS时:

在测试类的所有方法执行之前,就会销毁当前存在的上下文,重新创建一个全新的上下文供整个测试类使用。

这种场景适合:你希望这个测试类的所有方法都不受之前其他测试类留下的上下文状态影响,从头开始。

示例代码:

@SpringBootTest
@DirtiesContext(mode = DirtiesContext.Mode.BEFORE_CLASS)
public class OrderServiceTest {

    @Autowired
    private OrderService orderService;

    @Test
    void testCreateOrder() {
        orderService.createOrder("ORD-001");
        assertTrue(orderService.exists("ORD-001"));
    }

    @Test
    void testCancelOrder() {
        orderService.createOrder("ORD-002");
        orderService.cancelOrder("ORD-002");
        assertFalse(orderService.exists("ORD-002"));
    }
}

3. Mode.BEFORE_EACH_TEST_METHOD

指定这个mode时:

测试类里的每个测试方法执行之前,都会销毁当前上下文并重新创建一个全新的。这和你在每个方法上单独标注@DirtiesContext(mode = BEFORE_METHOD)的效果完全一样,但放在类上更简洁。

这种场景适合:测试类里的每个方法都需要独立的上下文,避免方法之间的状态干扰(比如某个方法修改了Bean的全局状态,会影响下一个方法)。

示例代码:

@SpringBootTest
@DirtiesContext(mode = DirtiesContext.Mode.BEFORE_EACH_TEST_METHOD)
public class ProductServiceTest {

    @Autowired
    private ProductService productService;

    @Test
    void testAddProduct() {
        productService.addProduct("Laptop");
        assertEquals(1, productService.getProductCount());
    }

    @Test
    void testRemoveProduct() {
        // 这里的productService是全新的,初始计数为0
        productService.addProduct("Phone");
        productService.removeProduct("Phone");
        assertEquals(0, productService.getProductCount());
    }
}

4. Mode.AFTER_EACH_TEST_METHOD

最后这个mode的行为是:

每个测试方法执行完成后,就将上下文标记为脏并销毁,下一个方法执行时重新创建上下文。

和上面的BEFORE_EACH类似,只是时机在方法执行后,适合那些执行完会严重污染上下文的方法,确保下一个方法不受影响。

总结一下:类级别的@DirtiesContext本质是批量配置整个测试类的上下文刷新策略,不用你在每个方法上重复标注,根据你的测试独立性需求选择对应的mode就好~

内容的提问来源于stack exchange,提问作者Kunal gupta

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 07:14:38