如何在@JdbcTest类之后设置Spring Boot以关闭连接池?

时间:2018-03-23 08:34:45

标签: java spring spring-boot integration-testing spring-jdbc

我们有使用Postgresql DB的大型系统,具有相当复杂的数据库结构。我们为该系统进行了许多与DB相关的集成测试。 由于复杂的数据库结构和代码中特定于postres的sql的使用,使用H2(或其他内存数据库)模拟postgres似乎非常不可靠。

因此,我们正在使用以下结构的junit测试:

@RunWith(SpringRunner.class)
@JdbcTest
@AutoConfigureTestDatabase(replace= AutoConfigureTestDatabase.Replace.NONE)
@Sql( ... schema creation, sample data, etc  )
@ContextConfiguration(classes = ... dao and service classes used in the test)

当你有2-3个测试类时,一切都很好。当你有10个以上的测试类时,问题就开始出现了。据我了解,SpringBoot为每个不同的上下文配置创建单独的连接池。为了尽可能地隔离测试,我们通常只在上下文配置中包含在测试中使用的组件。因此,SpringBoot会创建数十个连接池,这会导致连接池或jdbc驱动程序出现“连接太多”类型的错误。您可以逐个运行测试,但不能同时运行它们(所以告别CI)。

我们正在使用以下解决方法。以下代码段被复制粘贴到每个测试类:

// <editor-fold name='connection leaking fix'
@Autowired
private DataSource dataSource;
private static HikariDataSource hikariDataSource;

@Before
public void saveDataSource() {
    this.hikariDataSource = (HikariDataSource)dataSource;
}

@AfterClass
public static void releaseDataSource() {
    if (hikariDataSource != null) {
        hikariDataSource.close();
    }
}
// </editor-fold>

可行,但您必须记住,不应将该代码段粘贴到使用相同上下文配置的测试类。

问题 - 有没有办法告诉spring boot在每次测试类执行后关闭连接池,还是以任何方式限制spring boot创建的连接池数量?

1 个答案:

答案 0 :(得分:1)

@ M.Deinum是对的,解决问题的唯一方法是在不破解某些变通方法的情况下使用有限数量的配置。所以你可以使用这样的东西来测试DAO层:

@RunWith(SpringRunner.class)
@JdbcTest(includeFilters = @ComponentScan.Filter(Repository.class))
@AutoConfigureTestDatabase(replace= AutoConfigureTestDatabase.Replace.NONE)
@Sql(...)

或类似的东西来测试DAO和服务层:

@RunWith(SpringRunner.class)
@JdbcTest(includeFilters = {
    @ComponentScan.Filter(Repository.class),
    @ComponentScan.Filter(Service.class)
})
@AutoConfigureTestDatabase(replace= AutoConfigureTestDatabase.Replace.NONE)
@Sql(...)