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

Mockito Spy的doReturn未生效:静态日期返回值异常排查

问题分析:Mockito Spy未生效,currentDateTime()仍返回系统时间

你的核心错误是测试执行阶段调用了原始对象的方法,而非Spy对象的方法:

你在@BeforeEach中创建了serviceToTest原始实例,又基于它生成了spy对象,并且给spy配置了currentDateTime()的返回值,但测试时执行的是serviceToTest.calculateApiTokenExpireDate(),完全没用到spy对象,所以mock规则根本没生效,currentDateTime()还是执行原逻辑返回系统当前时间。

修正方案

方案1:调用Spy对象的方法

将测试中的执行代码改为调用spy对象的方法即可:

@Test
void calculateApiTokenExpireDate_return_plus_one_day_date() {
    /* prepare */
    doReturn(LocalDateTime.of(2023, 1, 24, 14, 1)).when(spy).currentDateTime();

    /* execute */
    // 改为调用spy对象的方法
    LocalDateTime tokenExpireDate = spy.calculateApiTokenExpireDate();

    /* test */
    assertEquals(2023, tokenExpireDate.getYear());
    assertEquals(1, tokenExpireDate.getMonthValue());
    assertEquals(25, tokenExpireDate.getDayOfMonth());
}

方案2:简化Spy创建逻辑

可以直接创建Spy实例,省去单独的原始对象,代码更简洁:

@BeforeEach
void beforeEach() {
    spy = Mockito.spy(new ServiceHelper());
    spy.oneTimeOutDatedMillis = 86400000;
}

@Test
void calculateApiTokenExpireDate_return_plus_one_day_date() {
    /* prepare */
    doReturn(LocalDateTime.of(2023, 1, 24, 14, 1)).when(spy).currentDateTime();

    /* execute */
    LocalDateTime tokenExpireDate = spy.calculateApiTokenExpireDate();

    /* test */
    assertEquals(2023, tokenExpireDate.getYear());
    assertEquals(1, tokenExpireDate.getMonthValue());
    assertEquals(25, tokenExpireDate.getDayOfMonth());
}

补充说明

Mockito Spy的作用是包装原始对象,允许你替换特定方法的行为,但所有方法调用必须通过Spy对象发起,才能触发mock规则。如果直接调用原始对象,Spy的配置对它完全没有影响。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 13:25:24