我有几个用于从数据库中检索信息的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());
}
}
任何想法都会受到赞赏。
谢谢!
答案 0 :(得分:11)
请看下面的链接:
答案 1 :(得分:5)
我建议打破对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 :(得分:2)
要为此编写真正的单元测试,您将无法触及真正的数据库。 但是,您可能会发现将实际DataSource传递给基础数据库更为实际,并且测试getBusinessSegments()方法会返回0,1和许多结果,具体取决于您传入的cc和ll值。
值得研究的另一个选择是传入一个嵌入式Java DB的DataSource,它是在setUp / @ Before方法中使用您的模式初始化的。我想你真正想要测试的是SELECT ...查询正确地映射到模式,所以这样的测试会捕获运行时出现的任何错误,例如,模式发生变化。