使用 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 进行集成测试的主要内容,如果未能解决你的问题,请参考以下文章
在 Maven 中使用带有 Flyway 和 jOOQ 的嵌入式数据库进行持续集成