Как написать тесты Junit для этого кода со 100% покрытием кода? - PullRequest
0 голосов
/ 09 июля 2019

Тесты Junit для приложения Spring Boot.

У кого-нибудь есть предложения, как мне этого добиться, используя JUnit и Mockito?

@Autowired
JdbcTemplate jdbcTemplate;

public List<Student> getStudentDetails(String department) {

   List<Student> results = new LinkedList<String>();
   results =  jdbcTemplate.query("SELECT * FROM STUDENT WHERE DEPARTMENT = ?", new PreparedStatementSetter() {
        @Override
        public void setValues(PreparedStatement preparedStatement) throws SQLException {
            preparedStatement.setString(1, department);
            preparedStatement.setFetchSize(10);
        }
    }, new ResultSetExtractor<List<Student>>() {
        @Override
        public List<Student> extractData(ResultSet rs) throws SQLException {
            List<Student> students = new ArrayList<>();
            while (rs.next()) {
                Student student = new Student<>();
                student.setDepartment(rs.getString("NAME"));
                student.setName(rs.getString("DEPARTMENT"));
                students.add(student);
            }
            return students;
        }
    });
   return results      
  }

1 Ответ

0 голосов
/ 10 июля 2019

Код, который у вас есть, связан с базой данных, и, по моему мнению, он должен быть протестирован с использованием какой-либо базы данных.Обычной практикой является использование встроенной базы данных (например, 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 методу.Затем я запускаю переопределенные методы аргументов и проверяю, что они работают так, как мы ожидаем.

...