如何在没有 @DirtiesContext 的情况下在 Quarkus 中实现集成测试?

问题描述

对于 Spring Boot,我使用 @DirtiesContext 来确保在每个测试用例之前清除数据库

Quarkus AFAIK 没有 @DirtiesContext 注释。相反,建议使用 @TestTransaction。这样,测试用例所做的更改会在测试用例结束时回滚。这适用于单元测试。但是,我正在努力了解如何将其用于集成测试。

我的集成测试使用放心来对控制器进行休息调用。一方面,我认为在控制器中使用 @TestTransaction 不是一个好主意。即使我这样做了,当 rest 调用返回时,数据也会被擦除。如果我在控制器中使用@Transaction,我将无法为下一个测试用例擦除数据库

所以,我的问题是你们如何解决这个问题?在进行集成测试时,您如何确保拥有干净的上下文。

解决方法

似乎 Spring 的 @DirtiesContext 是一个:

指示与测试关联的 ApplicationContext 是脏的,因此应关闭并从上下文缓存中删除的测试注释。

如果测试修改了上下文,请使用此注释——例如,通过修改单例 bean 的状态,修改嵌入式数据库的状态等。请求相同上下文的后续测试将提供一个新的上下文。

这与通过回滚当前事务来清除数据库完全不同:这会破坏并重新创建整个 Spring 上下文。

使用 Quarkus @QuarkusTestProfile 可以达到同样的效果,here 描述为:

如果测试的配置文件与之前运行的测试不同,则 Quarkus 将在运行测试之前关闭并使用新的配置文件启动。这显然有点慢,因为它为测试时间增加了关闭/启动周期,但提供了很大的灵活性。

如果您只需要确保事务在测试后回滚,您需要做的就是注释测试方法,而不是控制器 使用 io.quarkus.test.TestTransaction,如 here 所述:

您可以在测试中使用标准的 Quarkus @Transactional 注释,但这意味着您的测试对数据库所做的更改将是持久的。如果您希望在测试结束时回滚所做的任何更改,您可以使用 io.quarkus.test.TestTransaction 注释。这将在事务中运行测试方法,但在测试方法完成后回滚它以恢复任何数据库更改。

您的应用程序代码将在由测试方法启动的事务中运行,执行您可以在测试方法中测试的事情,最后回滚以清除参与事务的任何持久状态。这有一些陷阱: (1) 如果您的逻辑在某个时候启动了一个新事务,它不会自动回滚。 (2) 如果你的逻辑改变了某种不参与交易的状态,这个改变不会回滚。