Mockito测试JDBC Template Query时遇空指针异常求助
排查jdbcTemplate.query()空指针异常的方案
我来帮你一步步排查这个空指针问题,结合你的代码场景,可能有以下几个常见原因及解决办法:
1. 确认jdbcTemplate实例已被正确Mock并注入到被测类
空指针最常见的原因就是被测类中的jdbcTemplate对象是null,根本没拿到你Mock的实例。请检查:
- 测试类中是否给jdbcTemplate加上了
@Mock注解 - 被测类是否用
@InjectMocks注解注入,或者你是否手动把Mock的jdbcTemplate设置到了被测类的对应字段里 - 如果用JUnit 4,测试类要加上
@RunWith(MockitoJUnitRunner.class);如果是JUnit 5,要加@ExtendWith(MockitoExtension.class),或者在@BeforeEach/@Before方法里调用MockitoAnnotations.openMocks(this)来初始化Mock实例
2. 修正Mockito测试代码的两处错误
你的测试用例里有两个明显的问题,可能导致Mock失效进而引发空指针:
- 匹配器导入错误:确保你用的是Mockito的匹配器,而不是Hamcrest的。Mockito 2.x及之前用
org.mockito.Matchers,3.x+用org.mockito.ArgumentMatchers,不要导入org.hamcrest.Matchers - 返回值类型不匹配:业务代码中
jdbcTemplate.query()返回的是List<B>,但你的测试代码里thenReturn(B)是返回单个B对象,类型不匹配会导致Mock逻辑不生效。应该改成返回一个List实例,比如:Mockito.when(jdbcTemplate.query(anyString(), any(RowMapper.class))) .thenReturn(Collections.singletonList(new B())); // 返回List<B>类型
3. 解决lambda作为RowMapper的匹配兼容性问题
业务代码里用lambda实现了RowMapper,由于泛型擦除,有时候any(RowMapper.class)可能无法精准匹配。你可以尝试用带泛型的匹配器来明确类型,避免匹配失败:
Mockito.when(jdbcTemplate.query(anyString(), ArgumentMatchers.<RowMapper<B>>any())) .thenReturn(Collections.singletonList(new B()));
4. 验证Mock是否被实际调用
可以在测试方法末尾加上验证逻辑,确认你的Mock实例真的被业务代码调用了:
Mockito.verify(jdbcTemplate).query(anyString(), any(RowMapper.class));
如果这行代码抛出Wanted but not invoked异常,说明业务代码根本没用到你Mock的jdbcTemplate,大概率是被测类里的jdbcTemplate还是null或者是真实实例。
内容的提问来源于stack exchange,提问作者JDeveloper
相关产品推荐
相关产品推荐

