Java,Spring:使用Mockito测试DAO的DataAccessException

Java,Spring:使用Mockito测试DAO的DataAccessException,java,spring,unit-testing,jdbc,Java,Spring,Unit Testing,Jdbc,我试图增加我的测试覆盖率,所以我想知道,您如何测试DAO中抛出的DataAccessExceptions,例如在一个简单的findAll方法中,该方法只返回数据源中的所有数据?在我的例子中,我使用的是SpringJDBCTemplates 对于一般测试,我有一个带有@Before注释的setUp方法,模拟使用的jdbcTemplate,在DAO中设置它,并模拟所有jdbc调用。现在强制像create方法这样的对象使用DataAccessException非常简单,只要在使用正确的主键调用crea

我试图增加我的测试覆盖率,所以我想知道,您如何测试DAO中抛出的DataAccessExceptions,例如在一个简单的findAll方法中,该方法只返回数据源中的所有数据?在我的例子中,我使用的是SpringJDBCTemplates

对于一般测试,我有一个带有@Before注释的setUp方法,模拟使用的jdbcTemplate,在DAO中设置它,并模拟所有jdbc调用。现在强制像create方法这样的对象使用DataAccessException非常简单,只要在使用正确的主键调用create语句时抛出异常即可

然而,我真的不知道如何处理像简单的findAll方法这样不接受任何输入参数的方法。测试有效的实现是直截了当的,但是如何在不影响其他测试或方法的情况下模拟没有DB连接呢

这将是我想测试的方法的具体实现:

  public List<SomeObject> findAll() throws PersistenceException {
    final String sql = "SELECT * FROM SomeObject";

    try {
      return jdbcTemplate.query(sql, new JdbcSomeObjectMapper());
    } catch (DataAccessException ex) {
      LOG.error(ex.getMessage());
      throw new PersistenceException(ex.getMessage());
    }
  }
public List findAll()引发PersistenceException{
最后一个字符串sql=“SELECT*fromsomeobject”;
试一试{
返回jdbcTemplate.query(sql,新的JdbcSomeObjectMapper());
}捕获(DataAccessException ex){
LOG.error(例如getMessage());
抛出新的PersistenceException(例如getMessage());
}
}

这将只返回数据源中的所有对象。测试有效调用很容易,因为我可以模拟jdbcTemplate.query调用,但我永远不会进入catch块,除非在检索数据时出现连接故障,这就是我要测试的。使用Mockito可以模拟一个类和该特定类的方法调用。当对模拟对象调用特定方法时,还可以要求该对象抛出异常。首先必须模拟jdbcTemplate,然后存根异常

   //mocking JdbcTemplate
JdbcTemplate template = Mockito.mock(JdbcTemplate.class);
Mockito.when(template.query(Mockito.anyString(), (RowMapper<YourClass>)  Mockito.any(RowMapper.class))).thenThrow(EmptyResultDataAccessException.class);

    //or using EasyMock
 EasyMock.expect(template.query(Mockito.anyString(), (RowMapper<YourClass>)  Mockito.any(RowMapper.class))).andThrow(new (typeofExecption));
//模仿JdbcTemplate
JdbcTemplate=Mockito.mock(JdbcTemplate.class);
Mockito.when(template.query(Mockito.anyString(),(RowMapper)Mockito.any(RowMapper.class)).thenThrow(EmptyResultDataAccessException.class);
//或者使用EasyMock
expect(template.query(Mockito.anyString(),(RowMapper)Mockito.any(RowMapper.class)))和row(new(typeofExecption));

您会测试什么?DAO不应该处理这个异常,它应该在堆栈中冒泡,直到可以处理为止,通常是通过向最终用户显示一条错误消息?它并没有真正处理它,它只是记录发生的异常并将新异常委托给下一层。它们实际上应该只在没有连接到数据库的情况下发生,这就是我想要测试的,而不破坏所有其他测试。Spring已经为您统一了与持久性相关的异常。我不认为仅仅为了将一个技术性的Spring持久性异常转换成另一个定制的持久性异常而将每个DAO的每个方法都弄乱有什么意义。无论如何,如果你想让我们展示如何对这种情况进行单元测试,你应该发布要测试的代码,以及你已经尝试过的测试内容。你是对的,我应该从一开始就这样做。更新了原始帖子。每个测试都应该独立于其他测试。他们都应该模拟测试需要检查的模板,然后使用该模拟创建一个DAO实例,然后调用该方法,检查它是否正确。再一次,如果你发布你的代码,这会容易得多。请注意,单元测试方法是非常无用的:您将检查您是否正在使用模板执行查询。那是什么测试?不多您仍然不知道查询是否正确,是否返回预期的数据,等等。