JUnit 5测试中Spring依赖注入为Null问题求助
问题核心原因
你遇到的userService始终为null的问题,根源在于手动创建的TestUser对象不在Spring容器的管理范围内:在EsportTrackerApplicationTests的contextLoads方法中,你通过new TestUser()实例化了TestUser,这个对象不是由Spring容器创建的,因此Spring无法为其完成依赖注入。
另外,启动类中的@ComponentScan("com.tracker.EsportTracker.service.impl")属于冗余配置——@SpringBootApplication注解已经内置了@ComponentScan功能,默认会扫描启动类所在包(com.tracker.EsportTracker)及其所有子包,无需额外添加。
解决方案
方案1:直接独立运行TestUser测试类
TestUser本身已经标注了@SpringBootTest,是合法的Spring Boot测试类,你可以直接运行该类的getUsers方法,无需通过EsportTrackerApplicationTests间接调用。
这种方式下,Spring会负责创建TestUser的实例并完成依赖注入,userService就能正常获取到实例。
方案2:在EsportTrackerApplicationTests中注入TestUser
如果需要在EsportTrackerApplicationTests中调用TestUser的方法,不要手动new对象,而是通过Spring注入TestUser:
修改EsportTrackerApplicationTests代码:
package com.tracker.EsportTracker; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; @SpringBootTest class EsportTrackerApplicationTests { @Autowired private TestUser testUser; // 注入Spring管理的TestUser实例 @BeforeAll public static void beforeClass() { System.out.println("before all Method"); } @AfterAll public static void afterAll() { System.out.println("after all Method"); } @BeforeEach public void beforeTest() { System.out.println("before test Method"); } @AfterEach public void afterTest() { System.out.println("after test Method"); } @Test void contextLoads() { System.out.println("Starting Test"); testUser.getUsers(); // 调用注入后的实例方法 System.out.println("End Test"); } }
清理启动类冗余配置
删除启动类中的@ComponentScan注解,简化后的启动类:
package com.tracker.EsportTracker; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Bean; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; @SpringBootApplication public class EsportTrackerApplication { public static void main(String[] args) { SpringApplication.run(EsportTrackerApplication.class, args); } @Bean public BCryptPasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } }
内容的提问来源于stack exchange,提问作者GotaKev

