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

Spring Boot中使用Clock.fixed()模拟LocalDate.now()失效问题排查

问题根源分析

你遇到的核心问题是:测试中Mock的Clock根本没被Spring容器里的Service用到。

让我拆解一下为什么会这样:

  1. 你用@SpringBootTest启动了完整的Spring上下文,Controller和SavingAccountService都是由Spring容器管理的Bean。
  2. 你通过@InjectMocks创建的SavingAccountService只是测试类里的一个本地对象,和容器中Controller依赖的那个Service完全是两个实例。
  3. 当你用TestRestTemplate发请求到Controller时,Controller调用的是容器里的Service,而这个Service注入的还是你在@SpringBootApplication中定义的默认Clock Bean,自然拿到的是当前系统时间。
解决方案(推荐方式)

用@MockBean替换@Mock,让Spring自动把容器里的Clock Bean换成你Mock的实例,这样整个上下文里的Service都会使用这个Mock的Clock:

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = RANDOM_PORT, classes = ChallengeApplication.class)
@ActiveProfiles("test")
public class SavingAccountTest {
    @MockBean // 替换成@MockBean,让Spring容器感知到这个Mock
    private Clock clock;
    private Clock fixedClock;
    
    @Autowired // 直接从容器注入Service,不用@InjectMocks
    private SavingAccountService savingAccountService;
    
    @Autowired
    private TestRestTemplate restTemplate;
    private URL base;
    @LocalServerPort
    int port;

    @Before
    public void setUp() throws MalformedURLException {
        base = new URL("http://localhost:" + port + "/your-api-endpoint");
        final LocalDate WEEKEND = LocalDate.of(2020, 07, 05);
        fixedClock = Clock.fixed(WEEKEND.atTime(9, 5).toInstant(ZoneOffset.UTC), ZoneId.of("CET"));
        
        // 配置Mock的Clock返回固定值
        when(clock.instant()).thenReturn(fixedClock.instant());
        when(clock.getZone()).thenReturn(fixedClock.getZone());
    }

    // 你的测试方法...
}
补充说明
  • @MockBean是Spring Boot提供的测试注解,专门用于在集成测试中替换Spring上下文里的Bean,这是官方推荐的容器内Mock方式。
  • 不要在@SpringBootTest这种启动完整上下文的测试中混合使用@InjectMocks和容器注入,很容易出现实例不匹配的问题。
  • 如果你之前的@InjectMocks是为了测试Service的逻辑,建议单独写单元测试(用@ExtendWith(MockitoExtension.class),不启动Spring上下文),而集成测试专注于验证整个调用链的正确性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 12:22:50