自定义行映射器的Junit代码覆盖率

时间:2020-10-31 12:42:57

标签: java spring spring-boot junit mockito

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

我可以在方法中模拟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:如果我做错了,什么是获得完整代码覆盖率的替代方法。

1 个答案:

答案 0 :(得分: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。

而且,由于几乎所有函数调用都是模拟的,因此我不确定您要在此处进行的测试,因此此测试实际上不会测试任何东西。

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

相关问题