increasing code coverage for JdbcTemplate mocking

冷暖自知 提交于 2020-05-11 11:01:54

问题


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

enter image description here

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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!