Mockito模拟queryForObject方法单元测试未全覆盖问题求助
解决Mockito模拟queryForObject未覆盖RowMapper代码的问题
你当前的单元测试直接让jdbcTemplate.queryForObject返回预先创建的People对象,导致传入的RowMapper lambda表达式完全没被执行,这就是那部分代码没覆盖到的核心原因。要实现全覆盖,需要让RowMapper的逻辑真正跑起来,具体调整如下:
步骤1:模拟ResultSet对象
先创建一个模拟的ResultSet,并设置它的getInt、getString方法返回对应测试数据:
// 模拟ResultSet实例 ResultSet mockRs = mock(ResultSet.class); when(mockRs.getInt("id")).thenReturn(1); when(mockRs.getString("first_name")).thenReturn("John"); when(mockRs.getString("last_name")).thenReturn("Doe");
步骤2:调整jdbcTemplate的模拟逻辑
不要直接返回People实例,而是捕获传入的RowMapper,调用它的mapRow方法并传入模拟的ResultSet:
when(jdbcTemplate.queryForObject( eq(GET_PEOPLE), // 匹配真实的SQL常量,测试更严谨 any(RowMapper.class), eq(department), eq(position) // 匹配实际传入的参数,可选但更贴近真实执行场景 )).thenAnswer(invocation -> { // 获取方法调用时传入的RowMapper RowMapper<People> rowMapper = invocation.getArgument(1); // 调用RowMapper的mapRow方法,传入模拟的ResultSet和行号(这里用0即可) return rowMapper.mapRow(mockRs, 0); });
步骤3:验证逻辑(可选)
如果需要确保ResultSet的方法被正确调用,可以添加验证语句:
verify(mockRs).getInt("id"); verify(mockRs).getString("first_name"); verify(mockRs).getString("last_name");
这样调整后,RowMapper里的new People().setId(...).setFirstName(...).setLastName(...)代码就会被实际执行,从而实现代码行的全覆盖。
内容的提问来源于stack exchange,提问作者Ahmad Wijaya
相关产品推荐
相关产品推荐

