如何在每种测试方法后重置/删除 Quarkus 中的 H2 数据库以使其独立?

我在我的 Quarkus 项目中使用带有 @QuarkusTestResource 注释的 H2 数据库。每种测试方法都在进行测试并检查是否存在一定数量的用户等。

我面临的问题是每次测试运行后都不会重置数据库,这就是为什么测试失败的原因,因为他们正在获得先前测试运行的结果。

@QuarkusTestResource(value = H2DatabaseTestResource.class)
class UserServiceTest {

    @Inject
    UserService userService;

    @Inject
    UserRepository userRepository;

    private User userA;
    private User userB;

    @Transactional
    @BeforeEach
    void setUp() {
        userA = new User();
        userA.setEmail("a");
        userA.setName("a");

        userB = new User();
        userB.setName("b");
        userB.setEmail("b");

        userRepository.persist(userA);
        userRepository.persist(userB);
    }

    @Test
    void testA(){
       //count == 2
    }

    @Test
    void testA(){
       //count == 4
    }

}

如何在每次测试后重置 H2 数据库以使它们彼此独立?

stack overflow How to reset / drop H2 database in Quarkus after each test method to make them independed?
原文答案

答案:

作者头像

检查以下 JUnit 扩展(使用 Flyway),它可以满足您的需求: https://github.com/radcortez/flyway-junit5-extensions

它还有一个 Quarkus 示例: https://github.com/radcortez/flyway-junit5-extensions/tree/master/examples/quarkus

注意:我遇到了同样的问题,所以我写了这个扩展来解决用例。请让我知道这是否可以解决您的问题。如果没有,我很乐意增强扩展。

作者头像

我想 TestContainers 可以解决你的问题。

有一个关于数据库的 specific chapter ,它们的初始化可以用不同的方式完成。

您还可以使用内存数据库来避免使用物理数据库。

作者头像

我在每个测试中都使用 @TestTransaction 而不是 @Transaction

@QuarkusTest
public class TestInvoiceRepositoryfindAllInvoicesToBePaid {

  @Inject
  MyRepository myRepository;

  @Test
  @TestTransaction
  public void do_something_in_database_01() {
    // it generates and persist data I need for my test
    generateTestData();
    // test my repo method to make sure it does what I want
    MyObject myObject = myRepository.findSomething();
    assertNotNull(myObject);
  }

  @Test
  @TestTransaction
  public void do_something_in_database_02() {
    // here I need to insert the data again, because
    // the previous test rolled everything back at the end of it
    generateTestData();
    // test my repo method to make sure it does what I want
    myRepository.findSomething2();
  }

  private void generateTestData() {
    ...
    ...
    ...
    myRepository.persist(something);
  }
}