JUnit5测试JDBI服务时Service中Jdbi注入为空问题排查
问题原因与解决方案
核心问题
测试类中用@InjectMocks创建的SurveyssService实例不在Spring容器的管理范围内,Spring的@Autowired自动装配机制不会对其生效,所以服务内部的Jdbi字段会是null。而测试类直接@Autowired的Jdbi是Spring上下文管理的Bean,因此能正常执行查询。
解决方案
方案1:直接通过Spring容器注入服务实例
把测试类里的@InjectMocks换成@Autowired,让SurveyssService由Spring容器管理,自动完成内部Jdbi的注入:
@SpringBootTest(classes = DxSurveyManagementApiApp.class) class SurveyssServiceTest { @Autowired Jdbi jdbi; @Autowired // 替换@InjectMocks为@Autowired SurveyssService surveyssService; @Test void surveyByNameTest() { List<Map<String, Object>> tables = jdbi.withHandle(handle -> handle.createQuery(SqlQueryConstants.GET_BY_GUID).bind("survey_guid", "3cb00b4a-d00f-40d3-b9b9-902893d852b8").mapToMap().list()); System.out.println(tables); // 此时服务内部的Jdbi已被Spring注入,可正常调用 surveyssService.surveyByGuid("3cb00b4a-d00f-40d3-b9b9-902893d852b8"); } }
方案2:结合Mockito与Spring注入(需Mock其他依赖时)
如果测试中需要MockSurveyssService的其他依赖,可用@SpyBean替代@InjectMocks,让服务实例由Spring创建,同时允许Mockito拦截方法:
@SpringBootTest(classes = DxSurveyManagementApiApp.class) class SurveyssServiceTest { @Autowired Jdbi jdbi; @SpyBean // 使用@SpyBean替代@InjectMocks SurveyssService surveyssService; @Test void surveyByNameTest() { List<Map<String, Object>> tables = jdbi.withHandle(handle -> handle.createQuery(SqlQueryConstants.GET_BY_GUID).bind("survey_guid", "3cb00b4a-d00f-40d3-b9b9-902893d852b8").mapToMap().list()); System.out.println(tables); surveyssService.surveyByGuid("3cb00b4a-d00f-40d3-b9b9-902893d852b8"); } }
关键说明
@InjectMocks是Mockito的注解,仅负责手动注入Mockito管理的Mock/Spy对象,不参与Spring的依赖注入流程,因此无法自动填充Spring容器中的JdbiBean。@SpringBootTest会启动完整的Spring上下文,通过@Autowired或@SpyBean获取的Bean会自动完成所有依赖的装配。
内容的提问来源于stack exchange,提问作者Valentina Carrington
相关产品推荐
相关产品推荐

