【发布时间】:2009-07-17 14:18:06
【问题描述】:
我正在使用 mockito 测试一个简单的 DAO 层,但我发现了一个问题,基本上是一个难以测试的接口,我想知道您能否给我一些见解...
这是我要测试的方法:
public Person getById(UserId id) {
final Person person = new PersonImpl();
gateway.executeQuery(GET_SQL + id.getUserId(), new ResultSetCommand(){
public int work(ResultSet rs) throws SQLException {
if(rs.next()){
person.getName().setGivenName(rs.getString("name"));
person.getName().setFamilyName(rs.getString("last_name"));
}
return 0;
}
});
return person;
}
我使用 DatabaseGateway,它是我的 java 代码和 SQL 之间的接口,并且该方法接受一个匿名类,这是网关的方法 executeQuery:
public int executeQuery(String sql, ResultSetCommand cmd) {
try{
Connection cn = createConnection();
PreparedStatement st = cn.prepareStatement(sql);
int result = cmd.work(st.executeQuery());
cn.close();
return result;
}catch(Exception e){
throw new RuntimeException("Cannot Create Statement for sql " + sql,e);
}
}
问题是,由于那个匿名类,测试 PersonDAO 变得越来越困难。
如果有人提出更好的设计,我可以重构整个代码,甚至删除匿名类(我确信有一个更简单的,但我似乎找不到它)。
感谢大家的建议。
PD:如果您需要更多信息,请随时询问
编辑:很难做的测试
public void testGetPersonById(){
DatabaseGateway gateway = mock(DatabaseGateway.class);
when(gateway.executeQuery(anyString(),any(ResultSetCommand.class)));
PersonDAO person_dao = new PersonDAOImpl(gateway);
Person p = person_dao.getById(new UserId(Type.viewer,"100"));
}
看到了吗? ResultCommand 是模拟的一部分,我也有兴趣测试该代码...我应该为该特定命令进行单独测试吗?
【问题讨论】:
-
请举一个越来越难做的测试的例子。
-
我不太了解 Java,但我想说 ResultSetCommand 不相关。您正在测试 getPersonById 以确保它在给定有效 UserId 时返回正确的 Person,在给定无效 UserId 时抛出异常等。如果它正常工作,您不必关心它使用特定的 ResultSetCommand。
标签: java unit-testing refactoring mocking