Spring Boot单元测试中@Autowired注入Bean为NULL问题求助
嘿,我来帮你梳理下你遇到的两个核心问题,其实都是Spring Bean定义和测试上下文加载的小坑,咱们一步步解决:
1. 为啥不加@RunWith和@SpringBootTest时@Autowired变量是NULL?
这完全是正常现象!没有这两个注解的话,JUnit就是单纯跑你的测试方法,根本没启动Spring的应用上下文——Spring连容器都没起来,怎么给你注入sampleClass呢?所以这个变量自然就是null啦。
2. 加了注解后为啥报BeanCreationException?
这才是你要解决的关键问题!你在OtherSampleClass里写的@Bean方法犯了一个Spring的基础错误:
@Bean(name = "sampleBean") public void someMethod(){ .... }
Spring对@Bean方法有个硬性要求:必须返回你要注册到容器里的Bean实例,返回void的话,Spring根本拿不到要管理的对象,自然就会抛出创建Bean失败的异常。你说实际运行时正常?可能你生产环境的代码里这个方法不是返回void?或者有其他地方定义了同名的Bean?不管怎样,测试环境里这个写法肯定不对。
具体修复步骤
第一步:修正@Bean方法的返回类型
把someMethod的返回类型改成你实际要创建的Bean的类型,比如假设你要创建的是SomeService类型的Bean,修改后应该是这样:
@Bean(name = "sampleBean") public SomeService someMethod(){ // 在这里返回该类型的实例,比如初始化并返回对象 return new SomeService(); }
注意:一定要替换成你真实需要的Bean类型,绝对不能是void。
第二步:优化测试类(可选但推荐)
如果你只是想测试SampleClass的业务逻辑,没必要加载整个Spring Boot应用上下文,可以用更轻量的方式,用@MockBean模拟依赖的sampleBean,这样测试启动更快,也不会受真实Bean的影响:
@RunWith(SpringRunner.class) // 只加载SampleClass相关的上下文,缩小范围 @SpringBootTest(classes = SampleClass.class) public class SampleTest { @Autowired private SampleClass sampleClass; // 模拟依赖的sampleBean,不用加载真实的Bean实例 @MockBean private OtherSampleClass sampleBean; @Test public void testInput(){ String sampleInput = "hi"; String actualResponse = sampleClass.retrieveResponse(sampleInput); assertEquals("You typed hi", actualResponse); } }
第三步:确认包扫描范围
最后检查下你的Spring Boot主类(带@SpringBootApplication注解的那个类),确保它所在的包能覆盖SampleClass和OtherSampleClass的位置,不然Spring找不到这些类,还是会加载上下文失败。
内容的提问来源于stack exchange,提问作者alwaysStuckJava

