Как протестировать DAO клас?

Клас выводит список изданий, как его правильно протестировать? Создать мок для листа?

public class PeriodicalsDao {
    private static final Logger log = Logger.getLogger(PeriodicalsDao.class);


    public static List<Periodical> getPeriodicals() {

        List<Periodical> list = new ArrayList<>();
        Connection connection = ConnectionPool.getInstance().getConnection();

        String sql = "select * from periodicals";
        PreparedStatement ps;
        try {
            ps = connection.prepareStatement(sql);

            ResultSet rs = ps.executeQuery();
            while (rs.next()) {
                int id = rs.getInt("Periodicals_id");
                String name = rs.getString("name");
                int price = rs.getInt("price");
                String type = rs.getString("type");
                String description = rs.getString("description");

                Periodical periodical = new Periodical(id, name, price, type, description);
                list.add(periodical);
            }
            return list;

        } catch (SQLException e) {
            log.error("Ошибка", e);
        } finally {
            try {
                connection.close();
            } catch (SQLException e) {
                log.error("Ошибка", e);
            }
        }
        return Collections.emptyList();
    }

или лучше без моков обойтись? Или лучше DAO не тестить? так как это не имеет смысла, так как ты тестишь работу СУБД по сути


Ответы (1 шт):

Автор решения: Roman-Stop RU aggression in UA

В юнит тесте тестировать нужно не метод и не класс, а поведение. Что это значит?

PeriodicalsDao отвечает за сохранение и чтение изданий. Безотносительно его реализации нужно тестировать, что он умеет это делать. Издания как-то попадают в БД, правильно? Т.е. есть метод(-ы) вставки издания.

Имеет смысл создать тест, который будет:

  1. запускать in-memory БД (h2 например)
  2. создавать структуру БД (для этого идеально использовать те же DDL, что используются для создания структуры в проде)
  3. добавлять пару изданий используя метод вставки
  4. читать используя метод getPeriodicals и проверять, что данные сохранились успешно

Нужно чтоб в тесте можно было изменить конфигурацию (jdbc url), чтоб ConnectionPool соединялся с in-memory БД, которую использует тест.

это не имеет смысла, так как ты тестишь работу СУБД по сути

Нет, это не так. В классе есть определенная логика. Как минимум:

  1. из какой таблицы читаем
  2. какие столбцы в какое поле объекта ложим

Тест это все может (а по хорошему должен) проверить. Идеально, конечно, отделить выполение запроса от самого отображения (маппинга) столбцов в поля, тогда и тесты можно разнести, и тестировать эти аспекты функциональности отдельно без необходимости использовать БД в тестах самого отображения.

Смотрите, как это сделано в sping - можно это легко повторить. Тут пример https://www.tutorialspoint.com/springjdbc/springjdbc_rowmapper.htm

→ Ссылка