对使用 Spring JDBC 的 DAO 类进行单元测试

2022-09-04 20:14:54

我有几个DAO对象用于从数据库中检索信息,我真的很想为它们编写一些自动化测试,但我很难弄清楚如何做到这一点。

我正在使用Spring's来运行实际的查询(通过预准备语句)并将结果映射到模型对象(通过类)。JdbcTemplateRowMapper

如果我要编写单元测试,我不确定我会/应该如何模拟对象。例如,由于只有读取,我将使用实际的数据库连接而不是模拟jdbcTemplate,但我不确定这是对的。

下面是批处理中最简单的 DAO 的(简化)代码:

/**
 * 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());
    }

}

任何想法将不胜感激。

谢谢!


答案 1

答案 2

我建议打破你对类的依赖,改用接口,例如JdbcTemplateJdbcOperations

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
}

单元测试可以调用第二个构造函数,传入一个模拟对象。由于所有数据库操作都是通过对象执行的,因此您可以轻松地模拟它。JdbcOperationsjdbc

您的实时代码可以像以前一样调用第一个构造函数。