如何使用 Postgresql 后端对 DataSource 上的连接失败进行单元测试?

How do I unit test connection failures on a DataSource with Postgresql backend?

为了在数据库中断期间测试 Web 服务的行为,我想在我的单元测试中模拟连接失败。数据库后端是 Postgresql,代码使用了一些非标准的 SQL 查询,这使得很难使用普通的内存数据库进行测试。可以通过 DataSource 访问数据库连接,该 DataSource 将连接管理推迟到 ConnectionPool。

如何在单元测试中模拟 temporary/intermitent 数据库断开连接以验证正确的错误处理和从连接中断中恢复?

如@duffymo 所述,模拟是可行的方法。

如果您真的要进行单元测试,您已经会使用由模拟框架创建的模拟,因为单元测试需要隔离个体将 dependencies 替换为 test doubles 的单位。模拟框架是创建此类 测试替身 的最简单和最稳定的方法。

但我猜你是在用 UnitTesting Framework 执行 Integration Tests,称它们为 "unit tests"原因。

然而..

由于您的测试依赖于数据源的实际功能,因此 spy 将是一个不错的选择,如下所示:

class DatasourceUsageTest{    
    @Rule
    public ExpectedException exception = ExpectedException.none();
    @Test
    public void reportDatabaseOutage(){
        // arrange
        DataSource myDatasource = aquireDatasourceSomehow();
        DataSource spyOfMyDatasource = Mockito.spy(myDatasource);

        Mockito.doCallRealMethod() // first call
          .doThrow(new SqlException("Report this message") // second call (and all following) 
          .when(spyOfMyDatasource).methodExpectedToFail();

        SomeType testedUnit = createUnitAndInject(spyOfMyDatasource );

       // act call #1
       testedUnit.theMethodUsingDatasource(); 
       Mockito.verify(spyOfMyDatasource).methodExpectedToFail();

       // act call #2
       exception.expect(TheExceptionTypeToBeThrown.class);
       exception.expectMessage(EXCEPTION_MESSAGE_PREFIX + "Report this message"); 
       testedUnit.theMethodUsingDatasource(); 
      // Code below this will not be executed
    }
}

这里的问题(与任何 集成测试 一样)是您的数据库可能有一个真正的问题,在这种情况下,此测试在调用 #1 时失败(因此原因错误).