如何用@SpringBootTest测试标注@DependsOn的类并解决依赖bean缺失问题
问题根因
测试场景报错的核心原因是@SpringBootTest(classes = ClassIWantToTest.class) 配置仅会加载指定的ClassIWantToTest到Spring上下文,不会自动加载定义了someBean的SomeBeanConfig配置类,导致@DependsOn依赖的Bean缺失。
使用@MockBean时遇到NullBean类型不匹配是Spring Boot 2.2.x版本的已知兼容性问题:该版本下@MockBean的初始化时机晚于@DependsOn的依赖校验,Spring会先创建占位的NullBean,和预期的SomeClass类型不匹配。
解决方案
方案1:测试注解引入配置类(优先推荐)
修改@SpringBootTest注解,将SomeBeanConfig加入上下文加载列表,完全对齐生产环境的依赖逻辑:@SpringBootTest(classes = {ClassIWantToTest.class, SomeBeanConfig.class}) public class TestForClassIWantToTest { @Resource private ClassIWantToTest foo; // 其余测试逻辑不变 }方案2:内嵌配置类注册Mock Bean(适用于需要Mock依赖的场景)
若需要用Mock对象替代真实Bean,不要直接使用@MockBean,改为通过测试类内嵌的配置类提前注册Mock实例,保证注册时机早于@DependsOn校验:import org.mockito.Mockito; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @SpringBootTest(classes = ClassIWantToTest.class) public class TestForClassIWantToTest { @Configuration static class MockSomeBeanConfig { @Bean("someBean") public SomeClass mockSomeBean() { return Mockito.mock(SomeClass.class); } } @Resource private ClassIWantToTest foo; @Resource(name = "someBean") private SomeClass someBean; // 后续可自定义someBean的Mock行为 }方案3:调整包扫描范围
不想逐个指定加载类的场景下,可以直接指定业务代码的根包路径,让Spring自动扫描所有相关Bean:@SpringBootTest(scanBasePackages = "你的业务代码根包全路径") public class TestForClassIWantToTest { // 测试逻辑不变 }
内容的提问来源于stack exchange,提问作者André Risnes
相关产品推荐
相关产品推荐

