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

Spring Boot测试中无法覆盖Bean的问题排查

Spring Boot测试中覆盖Clock Bean失败的解决方法

问题根源

你的测试配置类MyTestConfiguration上额外添加了@ComponentScan,这会让Spring重复扫描com.kiteautotrade.autotrader包。而主应用类AutotraderApplication本身就带有@SpringBootApplication(该注解包含@ComponentScan和@Configuration功能),导致主配置的Clock Bean和测试配置的Clock Bean同时被加载。即便测试Bean加了@Primary,也可能因加载顺序问题,主配置Bean先完成注册,导致覆盖失效。

另外,@SpringBootTest已经指定了classes = AutotraderApplication.class,测试配置完全不需要重复执行组件扫描逻辑。

正确修改方案

  1. 移除测试配置类的@ComponentScan
    测试配置只需定义要覆盖的Bean,无需重复扫描组件,避免和主应用的扫描逻辑冲突。
  2. 使用@TestConfiguration替代@Configuration
    @TestConfiguration是Spring Boot专为测试场景设计的配置注解,它不会被自动扫描,仅在当前测试上下文生效,能更安全地覆盖主Bean。
  3. 保留@Primary注解
    该注解用于指定同类型Bean的优先级,确保测试Bean被优先注入。

修改后的测试代码如下:

package com.kiteautotrade.autotrader.integration;    
. . .

@ExtendWith(SpringExtension.class)
@RunWith(SpringRunner.class)
@SpringBootTest(classes = AutotraderApplication.class,
        webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class IntegrationTest {

    @TestConfiguration
    static class MyTestConfiguration {
        private static final ZoneId ZONE_ID = ZoneId.of("Asia/Kolkata");

        @Bean
        @Primary
        public Clock getClock() {
            return Clock.fixed(
                    LocalDateTime.of(2023, 4, 25, 9, 30)
                            .toInstant(ZoneOffset.ofHoursMinutes(5, 30)), ZONE_ID);
        }
    }
}

备选优化方案

如果上述方法仍未生效,可以在主配置的Clock Bean上添加条件注解,让主Bean仅在测试Bean不存在时才被创建:

// 主应用类的Clock Bean修改
@Bean
@ConditionalOnMissingBean
public Clock getClock() {
    return Clock.system(ZoneId.of("Asia/Kolkata"));
}

这样测试中的Clock Bean会优先被创建,主配置的Bean会自动跳过加载。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 04:12:44