увеличение покрытия кода для jdbctemplate mocking


Я издеваюсь над JdbcTemplate для юнит-тестов, поскольку не хочу ударить по фактической интеграции базы данных.

Но это уменьшает покрытие моего кода (красный цвет указывает на отсутствие покрытия).

Введите описание изображения здесь

Ниже приведен используемый фрагмент кода. То же самое происходит при использовании пользовательских картографов.

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

Любые идеи для increasing code покрытия в классе dao. Все методы не подходят для пользовательских отображателей строк в моем случае.

2 3

2 ответа:

Один из способов сделать это заключается в следующем:

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

Но, как вы можете видеть, это много кода, чтобы проверить сопоставитель строк:)

Лично я предпочел бы пойти с интеграционным тестом или переместить сопоставитель строк в свой собственный класс и модульное тестирование его отдельно.

Вы издеваетесь над jdbcTemplate, поэтому у вашего производственного jdbcTemplate нет шансов быть выполненным и уволить rowMapper. если вы действительно хотите издеваться над ним, то вы должны издеваться над запросом таким образом, чтобы он все еще запускал rowMapper и передавал ему поддельный ResultSet. вы также можете извлечь rowMapper и протестировать его индивидуально. но это заставляет вас тратить больше времени на написание тестов и ничего не получать взамен. не делай этого. код БД должен быть протестирован во время интеграционных тестов с реальной базой данных.