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

时间:2018-09-05 13:52:10

标签: java database unit-testing database-connection

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

如何在单元测试中模拟临时/间歇性数据库断开连接,以验证正确的错误处理以及从连接中断中恢复?

1 个答案:

答案 0 :(得分:1)

@duffymo提到的模拟是一种方法。

如果您真的要进行单元测试,您已经会使用由模拟框架创建的Mocks,因为 unit tests 要求通过替换它们的依赖性来隔离各个单元 test double 。模拟框架是创建此类 test doubles 的最简单,最稳定的方法。

但是我想您正在使用 UnitTesting Framework 执行集成测试,出于任何原因将它们称为“单元测试”。

但是..

由于您的测试依赖于数据源的真实功能,因此 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时失败(因此原因错误)。