如何用Mockito模拟接口实现类中ResultSet返回空列表的测试场景?
问题排查与解决方案
核心问题分析
- 注入冲突:同时使用
@Autowired和@InjectMocks会导致Spring优先注入容器中真实的MyService实现类实例,Mockito的JdbcTemplateMock无法被注入到目标对象,测试实际调用了真实数据库操作。 - Mock匹配失效:
when中传入的匿名RowMapper实例,和被测方法内部创建的RowMapper是两个不同对象,Mockito默认按对象相等性匹配,导致Mock条件永远不触发,无法返回预设的空列表。 - 方向错误:无需模拟
ResultSet,测试目标是**jdbcTemplate.query返回空列表时的判空逻辑**,直接Mockquery方法的返回值即可,不用关心RowMapper的具体执行。
修正后的测试代码
方案1:纯Mockito测试(不依赖Spring容器)
这种方式无需加载Spring上下文,测试速度更快,避免容器注入冲突:
@RunWith(MockitoJUnitRunner.class) public class MyClassTest { @Mock private JdbcTemplate jdbcTemplate; @InjectMocks private MyAccessor myService; // 直接使用实现类 @Test public void myTestMethod() { // 匹配任意SQL、任意RowMapper、任意参数,返回空列表 Mockito.when(jdbcTemplate.query( Mockito.anyString(), Mockito.any(RowMapper.class), Mockito.anyString() )).thenReturn(Collections.emptyList()); MyType result = myService.getMyMethod("value"); assertEquals(0, result.getFieldA()); assertEquals(0, result.getFieldB()); assertEquals(0, result.getFieldC()); assertEquals(0, result.getFieldD()); } }
方案2:结合Spring容器测试(替换容器中的JdbcTemplate为Mock)
如果必须依赖Spring上下文,用@MockBean替换容器中的真实实例:
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = { ".....", "....."}) @TestPropertySource(".....") public class MyClassTest { @MockBean // 替换容器中的JdbcTemplate为Mock实例 private JdbcTemplate jdbcTemplate; @Autowired private MyService myService; @Test public void myTestMethod() { Mockito.when(jdbcTemplate.query( Mockito.anyString(), Mockito.any(RowMapper.class), Mockito.anyString() )).thenReturn(Collections.emptyList()); MyType result = myService.getMyMethod("value"); assertEquals(0, result.getFieldA()); assertEquals(0, result.getFieldB()); assertEquals(0, result.getFieldC()); assertEquals(0, result.getFieldD()); } }
关键说明
- 禁止
@Autowired与@InjectMocks混用:前者是Spring注入注解,后者是Mockito的Mock注入注解,同时使用会引发注入优先级冲突。 - 使用宽松匹配:用
Mockito.any()系列方法(anyString()、any(Class.class))匹配参数,避免因匿名类、动态生成对象导致的匹配失败。 - 聚焦测试目标:测试核心是验证空列表场景下的默认值返回逻辑,直接Mock
jdbcTemplate.query的返回值即可覆盖该场景,无需深入模拟ResultSet或RowMapper。
内容的提问来源于stack exchange,提问作者MinionAttack
相关产品推荐
相关产品推荐

