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

Spring Boot Junit测试中如何正确配置@Configuration类以mock依赖的@ConfigurationProperties

问题根因

你遇到的mock返回null问题核心有两个:

  1. 你@Autowired注入的@Configuration类是Spring生成的CGLIB代理对象,依赖注入受Spring上下文管控,你手动mock的ConfigurationProperties没有被正确注入到代理对应的原始实例中
  2. 默认Spring上下文初始化时会优先加载真实的ConfigurationProperties bean,不会自动使用你生成的mock对象
推荐解决方案

方案1:纯单元测试(无需启动Spring上下文,性能最优)

直接实例化配置类,手动注入mock的Properties对象,完全脱离Spring代理逻辑的影响,适合只测业务逻辑的场景:

@ExtendWith(MockitoExtension.class)
public class MyConfigurationTest {
    // Mock所有依赖的ConfigurationProperties类
    @Mock
    private CustomProperties1 customProperties1;
    @Mock
    private CustomProperties2 customProperties2;

    // 直接把配置类作为被测对象,mock会自动注入
    @InjectMocks
    private MyConfig myConfig;

    @Test
    void testProtectedLogic() throws Exception {
        // 给mock对象打桩
        when(customProperties1.getTimeout()).thenReturn(1000);
        when(customProperties2.getEnableCache()).thenReturn(true);

        // 调用protected方法,如果测试类和配置类同包,可直接调用无需反射
        Method targetMethod = MyConfig.class.getDeclaredMethod("yourProtectedMethod");
        targetMethod.setAccessible(true);
        Object result = targetMethod.invoke(myConfig);

        // 验证返回结果符合预期
        assertThat(result).isNotNull();
    }
}

你可以把配置类里的protected方法改成包级访问权限,同包的测试类可以直接调用,不需要写反射代码。

方案2:Spring上下文集成测试(需验证@Bean注册逻辑时使用)

如果需要验证Bean在Spring上下文的注册逻辑,需要用@MockBean替换上下文里的真实Properties bean,Spring会自动把mock对象注入到配置类中:

@SpringBootTest(classes = MyConfig.class)
@EnableConfigurationProperties(value = {CustomProperties1.class, CustomProperties2.class})
public class MyConfigSpringTest {
    // 替换上下文中的真实Properties为mock对象
    @MockBean
    private CustomProperties1 customProperties1;
    @MockBean
    private CustomProperties2 customProperties2;

    @Autowired
    private MyConfig myConfig;
    @Autowired
    private ApplicationContext context;

    @Test
    void testBeanRegistration() {
        // 给mock对象打桩
        when(customProperties1.getServiceUrl()).thenReturn("https://test.api.com");

        // 从上下文获取@Bean方法生成的实例验证
        CustomService customService = context.getBean(CustomService.class);
        assertThat(customService.getApiUrl()).isEqualTo("https://test.api.com");
    }
}
注意事项
  • 不要在测试中直接调用配置类的@Bean方法,配置类的代理会拦截@Bean方法调用,多次调用默认返回同一个单例实例,直接调用你提取的业务逻辑方法即可
  • 除非必须验证Spring上下文的Bean加载逻辑,否则优先选择方案1的纯单元测试,执行速度更快,mock逻辑更可控

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 19:06:08