【问题标题】:Junit Code Coverage for Custom Row Mapper自定义行映射器的 Junit 代码覆盖率
【发布时间】:2020-10-31 12:42:57
【问题描述】:

我为 getEmployeeDetails 方法编写了一个测试类,其中包含一个过程,该过程将在游标中返回员工详细信息,实现了一个自定义行映射器来映射这些字段。

我能够在方法中模拟 StoredProcedure 调用并执行该方法,但是当我查看代码覆盖率时,自定义行映射器不包含在代码覆盖率中

下面是我的存储库类

public class EmployeeRepository {

@Autowired
private JdbcRepository jdbcRepository

public List<Employee> getEmployeeDetails() {


        SqlParameter[] sqlParameters = new SqlParameter[] {
                new SqlOutParameter("employeedetails", OracleTypes.CURSOR, new EmployeeListHandler()) };

        Map<String, Object> result = jdbcRepository.executeProcedure("employee_list_proc", sqlParameters, new HashMap<>());

        return (List<Employee>) result.get("employeedetails");



}
private class EmployeeListHandler implements RowMapper<Employee> {
    @Override
    public Employee mapRow(ResultSet rs, int rowNum) throws SQLException {

        Employee employee = new Employee();

        employee.setId(rs.getLong("id");
        employee.setName(rs.getString("name"));
        
        // Rest of the employee Attributes 


        return employee;
    }
}
}

下面是我的自定义 JbdcRepository 类

public Class JdbcRepository {

   public Map<String, Object> executeProcedure(String procedureName, SqlParameter[] sqlParameters,
        Map<String, Object> inputParams){

    StoredProcedure procedure = new GenericStoredProcedure();
    setDataSource(procedure);
    procedure.setSql(procedureName);
    procedure.setFunction(false);
    procedure.setParameters(sqlParameters);
    return procedure.execute(inputParams);

   }
}

下面是我的测试课

@Mock
private JdbcRepository jdbcRepository;

@Mock
private ResultSet rs;
    
@InjectMocks
private EmployeeRepository employeeRepository;


@Test
public void testEmployeeDetails() throws Exception{
    
   when(rs.next()).thenReturn(true).thenReturn(false);
   
   when(rs.getString(anyString())).thenReturn("TEST");
   
   when(jdbcRepository.executeProcedure(anyString(), any(SqlParameter[].class),
            anyMap())).thenReturn(new HashMap<>());
    
    employeeRepository.getEmployeeDetails();
    
    verify(jdbcRepository, times(1)).executeProcedure(anyString(), any(SqlParameter[].class),
            anyMap());
    
    verifyNoMoreInteractions(jdbcRepository);
}

我已经模拟了结果集,但是 EmployeeListHandler 仍然没有包含代码覆盖率,不确定我在哪里做错了..

编辑 1:如果我做错了,有什么替代方法来获得完整的代码覆盖率。

【问题讨论】:

    标签: java spring spring-boot junit mockito


    【解决方案1】:

    请注意:

    public List<Employee> getEmployeeDetails() {
    
    
            SqlParameter[] sqlParameters = new SqlParameter[] {
                    new SqlOutParameter("employeedetails", OracleTypes.CURSOR, new EmployeeListHandler()) };
    
            Map<String, Object> result = jdbcRepository.executeProcedure("employee_list_proc", sqlParameters, new HashMap<>());
    
            return (List<Employee>) result.get("employeedetails");
    
    
    
    }
    

    您创建了sqlParameters 并将EmployeeListHandler 对象添加为一个对象(如果它是参数)。

    然后你使用 sqlParametersexecuteProcedure 所以你的覆盖函数 mapRow 应该在调用 executeProcedure 时被调用,但你也 嘲笑它的召唤

      when(jdbcRepository.executeProcedure(anyString(), any(SqlParameter[].class),
                anyMap())).thenReturn(new HashMap<>());
    

    因此没有覆盖此函数,因为在您测试它时它永远不会被调用。

    编辑答案: 您应该单独测试 MapRow。

    而且,我不确定您要在这里测试什么,因为几乎所有的函数调用都是模拟的,所以这个测试并没有真正测试任何东西。

    如果您想实际测试对存储库的真实调用,您需要设置一个并对其进行测试。

    【讨论】:

    • 感谢 Raz,获得完整代码覆盖率的替代方法是什么...更新了问题。
    猜你喜欢
    • 2016-05-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-02
    • 2012-06-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多