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()); } }
任何想法将不胜感激。
谢谢!
请看下面的链接:
- 使用Spring和DbUnit测试SQL查询
- 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 …查询正确地映射到模式,所以这样的测试会捕获运行时出现的任何错误,例如,模式发生变化。