karthikmunna
karthikmunna

Reputation: 139

Junit Code Coverage for Custom Row Mapper

I have written a Test class for getEmployeeDetails Method contains a procedure which will return employee details in a cursor, a custom row mapper implemented to map those fields.

I am able to mock the StoredProcedure call in the method and execute the method, But when i look at the code coverage Custom Row Mapper is not included as part of the Code Coverage

Below is My Repository Class

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;
    }
}
}

Below Is My Custom JbdcRepository Class

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);

   }
}

Below Is my Test Class

@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);
}

I have mocked the resultset, But still Code coverage is not included for the EmployeeListHandler, Not sure where i am doing wrong ..

Edit 1: If i am doing wrong, what is alternative way to get the complete code coverage .

Upvotes: 0

Views: 784

Answers (1)

Rweinz
Rweinz

Reputation: 190

Notice that here:

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");



}

You created sqlParameters and added EmployeeListHandler object as one if it's parameters.

Then You used sqlParameters with executeProcedure so your overridden function mapRow is supposed to be called when executeProcedure is called, but you also mocked it's call

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

so there's no coverage on this function as it's never being called when you test it.

Answer for edit: You should test MapRow separately.

And also, I'm not sure what you're trying to test here since almost all your function calls are mocked so this test doesn't really test anything.

If you want to actually test a real call to the repository you'll need to setup one and test it.

Upvotes: 1

Related Questions