JUnit Mockito测试中Autowired嵌套Bean抛出空指针异常问题
解决CustomerService测试中EmployeeService空指针异常的方案
问题分析
你遇到的空指针是因为CustomerService实例中的EmployeeService依赖没有被正确注入:
- 如果测试类是Spring集成测试,@Autowired的CustomerService会从Spring容器获取,但如果EmployeeService没有被正确加载到容器(比如测试切片没包含该类),就会为空。
- 如果是纯单元测试,直接@Autowired无法获取容器Bean,必须用Mockito来模拟依赖并注入到CustomerService中。
方案1:Spring Boot集成测试(使用容器真实Bean)
如果想测试真实的服务交互,确保测试类加载正确的Spring组件:
// 测试类添加@SpringBootTest或@ServiceTest(Spring Boot 3.1+) @SpringBootTest class CustomerServiceTest { @Autowired private CustomerService customerService; // 无需手动注入EmployeeService,容器会自动注入到CustomerService中 @Test void testcustomerIdNotNull() { // 测试逻辑 Customer customer = customerService.getCustomerDetails(); // 断言等操作 } }
优化说明
如果用@ServiceTest(Spring Boot 3.1+),可以指定只加载需要的服务类,提升测试速度:
@ServiceTest(classes = {CustomerService.class, EmployeeService.class}) class CustomerServiceTest { // ... 同上 }
方案2:Mockito单元测试(模拟依赖)
如果只想单元测试CustomerService的业务逻辑,不需要加载完整Spring容器,用Mockito来模拟EmployeeService:
// 测试类添加@ExtendWith(MockitoExtension.class)启用Mockito支持 @ExtendWith(MockitoExtension.class) class CustomerServiceTest { // 创建EmployeeService的模拟对象 @Mock private EmployeeService employeeService; // 将模拟的EmployeeService自动注入到CustomerService中 @InjectMocks private CustomerService customerService; @Test void testcustomerIdNotNull() { // 模拟employeeService.getEmployee()的返回值 when(employeeService.getEmployee()).thenReturn(new Employee()); // 执行测试方法 Customer customer = customerService.getCustomerDetails(); // 断言验证 assertNotNull(customer); // 可验证employeeService.getEmployee()是否被调用 verify(employeeService, times(1)).getEmployee(); } }
常见错误排查
- 不要同时用
@Autowired和@InjectMocks处理同一个依赖:两种方式混用会导致依赖冲突,是空指针的常见诱因。 - 确保CustomerService中的EmployeeService字段非私有:如果是私有字段,需开启Mockito深层注入,或改用Setter注入方式。
- 若用Spring Boot Test,检查测试类包路径是否与主应用包一致,不一致需指定
@SpringBootTest(classes = 主应用启动类.class)。
内容的提问来源于stack exchange,提问作者Anil Nivargi
相关产品推荐
相关产品推荐

