问题
I am mocking JdbcTemplate for unit test cases, as don't want to hit actual database integration.
But it is decreasing my code coverage (Red indicates missing coverage).
Below is the snippet used. Same case happens by using user defined mappers.
final List<String> resultList = new ArrayList<String>();
resultList.add("test1");
resultList.add("test2");
final JdbcTemplate template = Mockito.mock(JdbcTemplate.class);
Mockito.when(
template.query(Mockito.anyString(), Mockito.any(Object[].class),
Mockito.any(RowMapper.class))).thenReturn(resultList);
sampleDao.setJdbcTemplate(template);
Any ideas for increasing code
coverage in dao class. All methods doesn't suit for user defined row mappers in my case.
回答1:
One way of doing this is as follows:
final List<String> resultList = new ArrayList<String>();
resultList.add("test1");
resultList.add("test2");
final JdbcTemplate template = mock(JdbcTemplate.class);
when(template.query(anyString(), any(Object[].class), any(RowMapper.class)))
.thenAnswer(new Answer<List<String>>() {
@Override
public Object answer(InvocationOnMock invocation) throws Throwable {
// Fetch the method arguments
Object[] args = invocation.getArguments();
// Fetch the row mapper instance from the arguments
RowMapper<String> rm = (RowMapper<String>) args[2];
// Create a mock result set and setup an expectation on it
ResultSet rs = mock(ResultSet.class);
String expected = "value returned by query";
when(rs.getString(1)).thenReturn(expected);
// Invoke the row mapper
String actual = rm.mapRow(rs, 0);
// Assert the result of the row mapper execution
assertEquals(expected, actual);
// Return your created list for the template#query call
return resultList;
}
});
But as you can see, it's a lot of code to test the row mapper :)
Personally, I would prefer going with an integration test OR moving the row mapper to a class of its own and unit testing it separately.
回答2:
you are mocking jdbcTemplate so your production jdbcTemplate have no chance of being executed and fire the rowMapper. if you really want to mock it then you have to mock query in a way it still fires the rowMapper and passes to it fake ResultSet. you can also extract the rowMapper and test it individually. but it makes you spend more time on writing tests and get nothing in return. don't do it. db code should be tested during integration tests with an actual database.
来源:https://stackoverflow.com/questions/28633173/increasing-code-coverage-for-jdbctemplate-mocking