使用 Jooq 进行集成测试

Posted

技术标签:

【中文标题】使用 Jooq 进行集成测试【英文标题】:Integration testing with Jooq 【发布时间】:2019-12-17 23:46:30 【问题描述】:

如何在 JUnit 中编写使用 JOOQ 作为数据访问层的集成测试,以及在测试完成后回滚?

Jooq 似乎只提供非常有限的事务管理。它提供了一种方法

DSLContext.transaction(TransactionalRunnable transactional)

如果传递的 lambda 抛出异常,此方法将回滚事务。但是如何使用 JUnit 集成测试来实现这一点并不明显。我真正想要的是不使用 Spring 的 @Transactional 接口的等价物。

@Transactional
class UserApiTest

  UserApi api;

  @Test
  public void testUpdateUserLastName() 
    User user = getUserByUsername();
    user.setLastName("NewLastName");
    api.updateUser(user);
    assertEquals("NewLastName", user.getLastName());
    // database should be unchanged after test completion because of automatic rollback
  


class UserApiImpl implements UserApi

  private final DSLContext db;

  @Override
  public void updateUser(LegacyUser user) 
    UserRecord userRecord = db.newRecord(USER, user);
    db.executeUpdate(userRecord);
  

任何建议将不胜感激。

【问题讨论】:

【参考方案1】:

比回滚更好的方法

首先,我建议您不要在此类集成测试中回滚事务,而是在测试后将数据库重置为已知状态。回滚失败的方式有很多种,例如:

调用具有无论如何都会提交的自主事务的存储过程 集成测试一些无论如何都会提交事务的服务 由于数据库的事务模型而导致回滚问题

如果您将数据库重置为众所周知的状态,您将避免上述所有问题,这些问题可能会使您在测试维护方面花费更多。

改用https://www.testcontainers.org 之类的东西。这是一个显示如何设置的示例:https://github.com/jOOQ/jOOQ/tree/main/jOOQ-examples/jOOQ-testcontainers-example

在测试结束时回滚

您不应该为此使用 jOOQ。您可以使用 Spring 的 JUnit 扩展,并进行所有测试 @Transactional。这样,每当您遇到断言错误时,您将自动回滚您的事务。此外,您的测试将自动成为事务性的。

这适用于简单的场景,但我相信您会再次遇到上述问题之一。

【讨论】:

以上是关于使用 Jooq 进行集成测试的主要内容,如果未能解决你的问题,请参考以下文章

如何在 PostgreSql 上使用 Jooq 级联截断?

在 Maven 中使用带有 Flyway 和 jOOQ 的嵌入式数据库进行持续集成

使用Mybatis和不同DB进行集成测试开发时如何做集成测试

使用 Airflow 进行集成测试

集成测试

使用 Flyway 进行集成测试