You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot服务单元测试中@Autowired注入的Service对象为NULL问题

解决Service单元测试中Autowired对象为Null的问题

问题根源

  1. 测试框架版本冲突:同时使用JUnit4的@RunWith(SpringJUnit4ClassRunner.class)和JUnit5的@ExtendWith(MockitoExtension.class),两者生命周期管理不兼容,导致Spring容器无法正确初始化并注入Service实例。
  2. Mock对象未关联Spring容器:即使Service完成初始化,Spring容器内的Service实例也无法获取@Mock创建的DAO对象——因为Mock对象不在Spring容器的管理范围内。

解决方案

方案一:纯Mockito轻量测试(无需Spring容器)

直接用Mockito注解完成Mock注入,无需启动Spring容器,适合纯单元测试场景:

@RunWith(MockitoJUnitRunner.class)
public class Ar11ApplicationServiceTest {
    
    @Mock
    private Ar11ApplicationDAO ar11ApplicationDAO;
    
    @InjectMocks
    private Ar11ApplicationServiceImpl ar11ApplicationService; // 直接实例化实现类,无需Autowired
    
    @Before
    void setUp() throws Exception {
        // 配置Mock行为,示例:
        // when(ar11ApplicationDAO.queryData()).thenReturn(testDataSet);
    }

    @Test
    void testService_HappyPath() {
        ar11ApplicationService.process();
        // 可添加验证逻辑,示例:
        // verify(ar11ApplicationDAO, times(1)).queryData();
    }
}

方案二:JUnit4结合Spring容器测试(需Spring依赖)

如果必须依赖Spring容器,需将Mock的DAO注册到容器中,确保Service能获取到该Mock实例:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = TestConfig.class)
public class Ar11ApplicationServiceTest {
    
    @Autowired
    private Ar11ApplicationService ar11ApplicationService;
    
    @Autowired
    private Ar11ApplicationDAO ar11ApplicationDAO;
    
    @Before
    void setUp() throws Exception {
        // 配置Mock行为
        Mockito.when(ar11ApplicationDAO.queryData()).thenReturn(testDataSet);
    }

    @Test
    void testService_HappyPath() {
        ar11ApplicationService.process();
    }
    
    // 测试专用配置类,注册Mock对象与Service
    @Configuration
    static class TestConfig {
        @Bean
        public Ar11ApplicationDAO ar11ApplicationDAO() {
            return Mockito.mock(Ar11ApplicationDAO.class);
        }
        
        @Bean
        public Ar11ApplicationService ar11ApplicationService() {
            return new Ar11ApplicationServiceImpl(ar11ApplicationDAO());
        }
    }
}

方案三:迁移到JUnit5(推荐,更现代)

改用JUnit5的Spring整合注解,通过@MockBean自动将Mock对象注入Spring容器:

@SpringJUnitConfig(classes = Ar11ApplicationServiceImpl.class)
public class Ar11ApplicationServiceTest {
    
    @MockBean // 自动注册Mock的DAO到Spring容器,并注入到Service中
    private Ar11ApplicationDAO ar11ApplicationDAO;
    
    @Autowired
    private Ar11ApplicationService ar11ApplicationService;
    
    @BeforeEach
    void setUp() throws Exception {
        // 配置Mock行为
        when(ar11ApplicationDAO.queryData()).thenReturn(testDataSet);
    }

    @Test
    void testService_HappyPath() {
        ar11ApplicationService.process();
    }
}

关键说明

  • @InjectMocks:Mockito提供的注解,自动将@Mock标注的对象注入到目标实例,无需Spring容器,适合快速单元测试。
  • @MockBean:Spring官方提供的注解,创建Mock对象并注册到Spring容器,替换同类型的原生Bean,确保Autowired的Service能获取到Mock实例。
  • 禁止混用JUnit4与JUnit5的测试注解,两者生命周期机制不同,会导致容器初始化异常。

内容的提问来源于stack exchange,提问作者gene b.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 22:32:25