使用 Spring Boot 和 Liquibase 时如何在每次集成测试后清理数据库表?

Jul*_*nel 4 java liquibase spring-boot testcontainers

我有一个副项目,我正在使用 Spring Boot、Liquibase 和 Postgres。

我有以下测试序列:

test1();
test2();
test3();
test4();
Run Code Online (Sandbox Code Playgroud)

在这四个测试中,我创建了相同的实体。由于我没有在每个测试用例之后从表中删除记录,因此出现以下异常:org.springframework.dao.DataIntegrityViolationException

我想通过以下约束来解决这个问题:

  1. 我不想使用@repository来清理数据库。
  2. 我不想杀死数据库并在每个测试用例上创建它,因为我正在使用 TestContainers 并且这样做会增加完成测试所需的时间。

简而言之:如何在每个测试用例之后从一个或多个表中删除记录,而无需 1) 使用@repository每个实体的 2) 在每个测试用例上终止并启动数据库容器?

Mar*_*arc 10

用 注释您的测试类@DataJpaTest。从文档中:

默认情况下,用 @DataJpaTest 注释的测试是事务性的,并在每个测试结束时回滚。它们还使用嵌入式内存数据库(替换任何显式或通常自动配置的数据源)。

例如使用 Junit4:

@RunWith(SpringRunner.class)
@DataJpaTest
public class MyTest { 
//...
}
Run Code Online (Sandbox Code Playgroud)

使用 Junit5:

@DataJpaTest
public class MyTest { 
//...
}
Run Code Online (Sandbox Code Playgroud)

  • @user7655213,我不同意并认为你的方法应该是首先要做的事情,在其他任何事情之前将测试声明为“@Transactional”。如果这不起作用,请尝试其他替代方案。`@DataJpaTest` 专门用于仅关注 JPA 功能的测试,如文档所指定:https://docs.spring.io/spring-boot/docs/current/api/org/springframework/boot/test/autoconfigure/ orm/jpa/DataJpaTest.html (3认同)

Jul*_*nel 5

我发现这样做的最简单方法如下:

  1. 注入一个 JdbcTemplate 实例
@Autowired
private JdbcTemplate jdbcTemplate;
Run Code Online (Sandbox Code Playgroud)
  1. 使用 JdbcTestUtils 类从您需要的表中删除记录。
JdbcTestUtils.deleteFromTables(jdbcTemplate, "table1", "table2", "table3");
Run Code Online (Sandbox Code Playgroud)
  1. 在使用@After或@AfterEach在您的测试类中注释的方法中调用此行:
@AfterEach
void tearDown() throws DatabaseException {
    JdbcTestUtils.deleteFromTables(jdbcTemplate, "table1", "table2", "table3");
}
Run Code Online (Sandbox Code Playgroud)

我在这篇博文中找到了这种方法: 使用测试容器进行轻松集成测试