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

Mockito测试遗留代码时,如何验证Context状态值的修改?

解决Mockito测试中无法验证Context状态更新的问题

你的测试失败的核心原因是:Mockito的RETURNS_DEEP_STUBS创建的深层mock不会自动维护对象状态。你预设了context.getState().getValue()返回4.12345,这个mock的getValue()方法只会一直返回这个固定值,哪怕你调用了setValue()——因为mock不是真实的对象,它没有实现“调用setValue就更新内部值”的逻辑。

要验证process()方法是否正确调用了setValue并传入了正确的参数,你需要拆分mock层级,手动mock每个依赖对象,然后捕获交互行为或者验证参数。

修改后的测试代码

@RunWith(MockitoJUnitRunner.class)
public class TestSampleClass {
    SampleClass sample = new SampleClass();

    @Mock
    private Context context;
    @Mock
    private State state; // 假设State是context.getState()返回的类型

    @Test
    public void testProcess() {
        // 1. 预设context.getState()返回我们mock的State对象
        Mockito.when(context.getState()).thenReturn(state);
        // 2. 预设state.getValue()返回初始值4.12345
        Mockito.when(state.getValue()).thenReturn(4.12345);

        // 执行被测方法
        sample.process(context);

        // 方式一:直接验证setValue是否被调用了正确的参数
        Mockito.verify(state).setValue(4.123);

        // 方式二:如果MathUtil.roundToThree的结果可能有精度问题,用ArgumentCaptor捕获参数再断言
        ArgumentCaptor<Double> captor = ArgumentCaptor.forClass(Double.class);
        Mockito.verify(state).setValue(captor.capture());
        assertEquals(4.123, captor.getValue(), 0.0001); // 用更小的精度阈值更稳妥
    }
}

关键说明

  • 避免使用RETURNS_DEEP_STUBS:深层mock虽然写起来简洁,但在需要验证交互时会变得不直观,而且不利于排查问题。拆分mock层级(分别mock Context和State)是更清晰的做法。
  • 验证交互而非状态:因为mock没有真实状态,所以不能通过调用getValue()来判断是否更新,而是要验证setValue()是否被调用了预期的参数——这是Mockito测试无状态mock的标准方式。
  • 精度问题:断言浮点数时,建议使用一个极小的阈值(比如0.0001),而不是0.0,避免因为浮点数计算的精度误差导致测试失败。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 07:01:39