unit testing使用Spring JDBC的DAO类

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

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

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

这是批次中最简单的DAO的(简化)代码:

 /** * Implementation of the {@link BusinessSegmentDAO} interface using JDBC. */ public class GPLBusinessSegmentDAO implements BusinessSegmentDAO { private JdbcTemplate jdbcTemplate; private static class BusinessSegmentRowMapper implements RowMapper { 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 getBusinessSegments(String cc, String ll) { return jdbcTemplate.query( new GetBusinessSegmentsPreparedStatementCreator(cc, ll), new BusinessSegmentRowMapper()); } } 

任何想法将不胜感激。

谢谢!

请看下面的链接:

  1. 使用Spring和DbUnit测试SQL查询
  2. MockObjects或DBUnit,用于使用JdbcTemplate测试代码

希望有所帮助。

编辑:

这是RowMapperTests的GitHub版本,以便于参考。

我建议打破你对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 } 

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

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

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

值得研究的另一个选择是传入一个嵌入式Java DB的DataSource,该数据源是在setUp / @ Before方法中使用您的模式初始化的。 我想你真正想要测试的是SELECT …查询正确地映射到模式,所以这样的测试会捕获运行时出现的任何错误,例如,模式发生变化。