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

Mockito @Mock对象无视新when..return定义返回同一对象问题排查

问题原因分析

你遇到的问题核心是测试实例生命周期导致的Mock对象共享冲突:

  • 你使用了@TestInstance(TestInstance.Lifecycle.PER_CLASS),这会让整个测试类只生成一个实例,所有测试方法共用同一个@Mock标记的DateMgr对象。
  • 即使你尝试重置Mock,若时机或方式不对,之前测试方法设置的存根依然会残留,导致后续测试的Mock行为不符合预期。

解决方案

方案1:改用默认测试实例生命周期(推荐)

直接删除@TestInstance(TestInstance.Lifecycle.PER_CLASS)注解,JUnit5默认采用PER_METHOD模式——每个测试方法都会创建全新的测试类实例,@Mock和@InjectMocks也会重新初始化,彻底隔离不同测试的Mock对象,避免互相干扰。

修正后的测试代码:

@ExtendWith(MockitoExtension.class)
public class TestSeries{ // 补充漏写的class关键字
    @Mock
    DateMgr dt;

    @InjectMocks
    Series s;

    @BeforeEach // 将@BeforeAll改为@BeforeEach,适配PER_METHOD的实例生命周期
    public void setup(){ 
        // 一些初始化操作 
    }

    // 生成指定数量日期的方法
    public List<LocalDate> getMockDates(int c){/* 实现代码 */}

    // 模拟dt.getDates(f,always)方法调用
    public void mockDates(List<LocalDate> dates){
         when(dt.getDates(any(), anyBoolean())).thenReturn(dates);
    }

    @Test
    public void test1(){
         List<LocalDate> dates1 = getMockDates(2);
         mockDates(dates1);
         List<LocalDate> processedDates = s.calculate(param1, param2); // 补充调用对象s.
         // 一些断言操作
    }

    @Test
    public void test2(){
         List<LocalDate> dates2 = getMockDates(3);
         mockDates(dates2);
         List<LocalDate> processedDates = s.calculate(param1, param2);
         // 一些断言操作
    }
}

方案2:保留PER_CLASS但强制重置Mock(适合必须共享实例的场景)

如果业务场景要求必须使用PER_CLASS生命周期,需在每个测试方法执行前重置Mock,确保存根状态干净:

@ExtendWith(MockitoExtension.class)
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
public class TestSeries{
    @Mock
    DateMgr dt;

    @InjectMocks
    Series s;

    @BeforeAll
    public void setup(){ 
        // 一些初始化操作 
    }

    @BeforeEach // 新增:每个测试前重置Mock
    public void resetMock(){
        Mockito.reset(dt);
    }

    // 其余方法同原代码,注意修正s.calculate()的调用和class关键字
}

额外修正点

原测试代码存在两处笔误,需同步修正:

  1. 测试类定义漏写class关键字:public TestSeries{ → public class TestSeries{
  2. 测试方法中调用calculate时漏写对象前缀:calculate(param1,param2) → s.calculate(param1,param2)

内容的提问来源于stack exchange,提问作者Ink Oveflow

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 22:52:47