Модульное тестирование класса DAO, использующего Spring JDBC - PullRequest
13 голосов
/ 23 марта 2011

У меня есть несколько объектов DAO, которые используются для извлечения информации из базы данных, и я действительно хочу написать для них несколько автоматических тестов, но мне сложно разобраться, как это сделать.

Я использую JdbcTemplate Spring для выполнения фактического запроса (с помощью подготовленного оператора) и сопоставления результатов с объектом модели (с помощью класса RowMapper).

Если бы я былчтобы написать модульные тесты, я не уверен, как бы я / должен издеваться над объектами.Например, поскольку есть только чтение, я бы использовал фактическое соединение с базой данных, а не издевался над jdbcTemplate, но я не уверен, что это верно.:

/**
 * Implementation of the {@link BusinessSegmentDAO} interface using JDBC.
 */
public class GPLBusinessSegmentDAO implements BusinessSegmentDAO {
    private JdbcTemplate jdbcTemplate;

    private static class BusinessSegmentRowMapper implements RowMapper<BusinessSegment>  {
        public BusinessSegment mapRow(ResultSet rs, int arg1) throws SQLException { 
            try {
                return new BusinessSegment(rs.getString(...));
            } catch (SQLException e) {
                return null;
            }
        }
    }

    private static class GetBusinessSegmentsPreparedStatementCreator 
        implements PreparedStatementCreator {
        private String region, cc, ll;
        private int regionId;

        private GetBusinessSegmentsPreparedStatementCreator(String cc, String ll) {
            this.cc = cc;
            this.ll = ll;
        }

        public PreparedStatement createPreparedStatement(Connection connection)
                throws SQLException {           
            String sql = "SELECT ...";

            PreparedStatement ps = connection.prepareStatement(sql);
            ps.setString(1, cc);
            ps.setString(2, ll);
            return ps;
        }
    }

    public GPLBusinessSegmentDAO(DataSource dataSource) {
        jdbcTemplate = new JdbcTemplate(dataSource);
    }

    public Collection<BusinessSegment> getBusinessSegments(String cc, String ll) {
        return jdbcTemplate.query(
                new GetBusinessSegmentsPreparedStatementCreator(cc, ll), 
                new BusinessSegmentRowMapper());
    }

}

Любая идея будет оценена.

Спасибо!

Ответы [ 3 ]

11 голосов
/ 23 марта 2011

Пожалуйста, посмотрите на ссылки ниже:

  1. Тестирование SQL-запросов с помощью Spring и DbUnit
  2. MockObjects или DBUnit для тестирования кода с использованием JdbcTemplate

Надеюсь, это поможет.

EDIT:

Вот версия RowMapperTests для GitHub для удобства.

5 голосов
/ 23 марта 2011

Я рекомендую отключить вашу зависимость от класса JdbcTemplate и использовать вместо этого интерфейс JdbcOperations, например,

public class GPLBusinessSegmentDAO implements BusinessSegmentDAO {
    private final JdbcOperations jdbc;

    public GPLBusinessSegmentDAO(DataSource dataSource) {
        this(new JdbcTemplate(dataSource));
    }

    public GPLBusinessSegmentDAO(JdbcOperations jdbc) {
        this.jdbc = jdbc;
    }

    // ... DAO methods here
}

Ваш модульный тест может вызывать второго конструктора, передавая фиктивный JdbcOperations объект. Поскольку все операции с БД выполняются с помощью объекта jdbc, вы можете легко смоделировать это.

Ваш живой код может вызывать первый конструктор, как и раньше.

2 голосов
/ 23 марта 2011

Чтобы написать настоящий модульный тест для этого, вы не будете касаться реальной базы данных. Тем не менее, вы можете посчитать более практичным передачу реального DataSource в ваш базовый db и тестирование метода getBusinessSegments (), возвращающего 0, 1 и многие результаты в зависимости от значений cc и ll, которые вы передаете.

Другой вариант, который стоит изучить, - передать источник данных встроенного Java DB , который был инициализирован с вашей схемой в методе setUp / @ Before. Полагаю, что вы действительно хотите проверить, так это то, что запрос SELECT ... правильно сопоставляется со схемой, поэтому такой тест будет перехватывать любые ошибки, возникающие во время выполнения, например, при изменении схемы.

...