繁体   English   中英

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

[英]Unit testing a DAO class that uses Spring JDBC

我有几个DAO对象,这些对象用于从数据库中检索信息,我确实想为它们编写一些自动化测试,但是我很难弄清楚该怎么做。

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

如果要编写单元测试,则不确定如何/应该模拟对象。 例如,由于只有读操作,因此我将使用实际的数据库连接,而不模拟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. 使用Spring和DbUnit测试SQL查询
  2. MockObjects或DBUnit使用JdbcTemplate测试代码

希望能有所帮助。

编辑:

这是RowMapperTestsGitHub版本,以方便参考。

我建议打破对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对象执行的,因此您可以轻松地对其进行模拟。

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

要为此编写一个真正的单元测试,您将不会接触真正的数据库。 但是,您可能会发现将实际的DataSource传递给基础数据库更实用,并测试getBusinessSegments()方法返回0、1和许多结果,具体取决于传递的cc和ll值。

另一个值得研究的选择是将嵌入式Java DB的数据源传递给setUp / @ Before方法中用您的架构初始化的数据库 我猜您真正要测试的是SELECT ...查询正确映射到架构,因此这种测试将捕获架构更改时在运行时出现的任何错误。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM