Код, который у вас есть, связан с базой данных, и, по моему мнению, он должен быть протестирован с использованием какой-либо базы данных.Обычной практикой является использование встроенной базы данных (например, h2).Люди делают это, поскольку с помощью модульных тестов невозможно проверить, действительно ли работает запрос, поскольку вы на самом деле его не запускаете.Поэтому я бы объединил интеграционные и модульные тесты для тестирования этого класса.
Модульный тест будет выглядеть примерно так:
@ExtendWith(MockitoExtension.class)
class StubTest {
@Mock
JdbcTemplate jdbcTemplate;
@InjectMocks
Stub stub;
@Test
void whenExecuteQuery_thenExtractDataCorrectly() throws SQLException {
//GIVEN
ArgumentCaptor<PreparedStatementSetter> setterCaptor = ArgumentCaptor.forClass(PreparedStatementSetter.class);
ArgumentCaptor<ResultSetExtractor> extractorCaptor = ArgumentCaptor.forClass(ResultSetExtractor.class);
//WHEN
stub.getStudentDetails("TEST");
//THEN
verify(jdbcTemplate).query(anyString(), setterCaptor.capture(), extractorCaptor.capture());
//AND
PreparedStatementSetter setter = setterCaptor.getValue();
PreparedStatement preparedStatement = Mockito.mock(PreparedStatement.class);
setter.setValues(preparedStatement);
verify(preparedStatement).setString(1, "TEST");
verify(preparedStatement).setFetchSize(10);
verifyNoMoreInteractions(preparedStatement);
//AND
ResultSetExtractor extractor = extractorCaptor.getValue();
ResultSet rs = Mockito.mock(ResultSet.class);
when(rs.next()).thenReturn(true).thenReturn(false);
when(rs.getString(anyString())).thenReturn("TEST","name");
verifyNoMoreInteractions(rs);
List<Student> students = (List<Student>) extractor.extractData(rs);
assertThat(students.get(0).getName()).isEqualTo("name");
assertThat(students.get(0).getDepartment()).isEqualTo("TEST");
}
}
Здесь я просто собираю аргументы с помощью бизнес-логики, которую мы отправляемк query
методу.Затем я запускаю переопределенные методы аргументов и проверяю, что они работают так, как мы ожидаем.