Spring中如何仅在测试配置侧禁止不需要的依赖注入?
解决方案
以下方案均仅需修改测试侧代码,无需改动主应用业务逻辑:
方案1:为缺失的依赖声明Mock Bean
如果你的项目使用Spring Boot,直接在测试配置类上加@MockBean注解声明缺失的Bean即可,Spring会自动创建Mockito模拟对象完成注入,不会触发后续的级联依赖校验:
@Configuration public class UnitTestConfig { @Inject private Environment env; // 声明所有缺失的依赖为Mock对象 @MockBean private B b; @MockBean private C c; @Bean public A a() { return new A(); } }
如果没有使用Spring Boot,可以手动在测试配置中创建Mock实例:
@Bean public B b() { return Mockito.mock(B.class); }
方案2:测试配置侧全局开启懒加载
直接在测试配置类上加@Lazy(true)注解,该配置下所有定义的Bean都会以懒加载模式初始化,只有单元测试实际用到的Bean才会触发依赖注入,未用到的Bean不会被初始化,自然也不会校验依赖是否存在:
@Configuration @Lazy(true) // 仅需添加这一行配置 public class UnitTestConfig { @Inject private Environment env; @Bean public A a() { return new A(); } }
方案3:自动注册所有缺失依赖为Mock(适配大量依赖缺失的场景)
如果缺失的依赖数量太多,逐个声明太繁琐,可以自定义BeanFactoryPostProcessor在测试上下文启动时自动为所有缺失的依赖注册Mock实例:
@Configuration public class UnitTestConfig { @Inject private Environment env; @Bean public static BeanFactoryPostProcessor mockMissingBeansPostProcessor() { return beanFactory -> { DefaultListableBeanFactory factory = (DefaultListableBeanFactory) beanFactory; // 遍历所有Bean的依赖,未定义的依赖自动注册为Mock for (String beanName : factory.getBeanDefinitionNames()) { BeanDefinition bd = factory.getBeanDefinition(beanName); for (String dependency : bd.getDependsOn()) { if (!factory.containsBean(dependency)) { Class<?> type = factory.getType(dependency); if (type != null) { factory.registerSingleton(dependency, Mockito.mock(type)); } } } } }; } @Bean public A a() { return new A(); } }
优先推荐方案2,改动最小,完全不侵入业务代码,也不需要额外维护Mock声明,只要保证单元测试实际用到的Bean链路的依赖存在即可。
内容的提问来源于stack exchange,提问作者Denise
相关产品推荐
相关产品推荐

