[英]How to clean database tables after each integration test when using Spring Boot and Liquibase?
我有一个附带项目,我正在使用 Spring Boot、Liquibase 和 Postgres。
我有以下测试序列:
test1();
test2();
test3();
test4();
在这四个测试中,我正在创建相同的实体。 由于我没有在每个测试用例之后从表中删除记录,因此出现以下异常: org.springframework.dao.DataIntegrityViolationException
我想通过以下约束来解决这个问题:
@repository
来清理数据库。 简而言之:如何在每个测试用例之后从一个或多个表中删除记录,而无需 1)使用每个实体的@repository
和 2)在每个测试用例上杀死并启动数据库容器?
我发现执行此操作的最简单方法如下:
@Autowired
private JdbcTemplate jdbcTemplate;
JdbcTestUtils.deleteFromTables(jdbcTemplate, "table1", "table2", "table3");
@After
或@AfterEach
注释的方法中调用此行:@AfterEach
void tearDown() throws DatabaseException {
JdbcTestUtils.deleteFromTables(jdbcTemplate, "table1", "table2", "table3");
}
我在这篇博文中找到了这种方法: 使用 Testcontainers 进行轻松集成测试
使用 @DataJpaTest 注释您的测试@DataJpaTest
。 从文档中:
默认情况下,使用 @DataJpaTest 注释的测试是事务性的,并在每个测试结束时回滚。 他们还使用嵌入式内存数据库(替换任何显式或通常自动配置的数据源)。
例如使用 Junit4:
@RunWith(SpringRunner.class)
@DataJpaTest
public class MyTest {
//...
}
使用 Junit5:
@DataJpaTest
public class MyTest {
//...
}
您可以在测试方法上使用 @Transactional。 这样,每个测试方法都将在其自己的事务括号内运行,并在下一个测试方法运行之前回滚。
当然,这仅在您没有对手动事务管理做任何奇怪的事情时才有效,并且它依赖于一些 Spring 引导自动配置魔术,因此可能无法在每个用例中使用,但它通常是高性能且非常简单的隔离测试用例的方法。
我认为这是 postgreSQL 最有效的方法。 你可以为其他数据库做同样的事情。 只需找到如何重新启动表序列并执行它
@Autowired
private JdbcTemplate jdbcTemplate;
@AfterEach
public void execute() {
jdbcTemplate.execute("TRUNCATE TABLE users" );
jdbcTemplate.execute("ALTER SEQUENCE users_id_seq RESTART");
}
我个人的偏好是:
private static final String CLEAN_TABLES_SQL[] = {
"delete from table1",
"delete from table2",
"delete from table3"
};
@After
public void tearDown() {
for (String query : CLEAN_TABLES_SQL)
{
getJdbcTemplate().execute(query);
}
}
为了能够采用这种方法,您需要使用 DaoSupport 扩展 class,并在构造函数中设置 DataSource。
public class Test extends NamedParameterJdbcDaoSupport
public Test(DataSource dataSource)
{
setDataSource(dataSource);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.