首页 > 解决方案 > How do I unit test connection failures on a DataSource with Postgresql backend?

问题描述

To test the behaviour of a web service during database outages I would like to simulate connection failures in my unit tests. The database backend is Postgresql and the code uses some non-standard SQL queries that make it hard to use a vanilla in-memory database for testing. The database connection is accessible through a DataSource that defers connection management to a ConnectionPool.

How can I simulate temporary/intermitent database disconnects in a unit test to verify correct error handling and recovery from connection outages?

标签: javadatabaseunit-testingdatabase-connection

解决方案


正如@duffymo 所提到的,模拟是要走的路。

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

但我猜你是在使用UnitTesting Framework执行集成测试,无论出于何种原因都称它们为“单元测试”。

然而..

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

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 时失败(因此原因错误)。


推荐阅读