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

wa7juj8i  于 2023-02-22  发布在  Spring
关注(0)|答案(5)|浏览(141)

我有一个副项目,我正在使用的Spring Boot ,Liquibase和Postgres。
我的测试顺序如下:

test1();
test2();
test3();
test4();

在这四个测试中,我创建了相同的实体,但是我没有在每个测试用例之后从表中删除记录,所以我遇到了以下异常:org.springframework.dao.DataIntegrityViolationException
我想用以下约束来解决这个问题:
1.我不想使用@repository来清理数据库。
1.我不想在每个测试用例中删除数据库并创建它,因为我正在使用TestContainers,这样做会增加完成测试所需的时间。
简而言之:如何在每个测试用例之后从一个或多个表中删除记录,而不需要1)使用每个实体的@repository和2)在每个测试用例上终止并启动数据库容器?

insrf1ej

insrf1ej1#

我发现的最简单的方法如下:
1.注入JdbcTemplate示例

@Autowired
private JdbcTemplate jdbcTemplate;

1.使用类JdbcTestUtils从表中删除所需的记录。

JdbcTestUtils.deleteFromTables(jdbcTemplate, "table1", "table2", "table3");

1.在测试类中使用@After@AfterEach注解的方法中调用此行:

@AfterEach
void tearDown() throws DatabaseException {
    JdbcTestUtils.deleteFromTables(jdbcTemplate, "table1", "table2", "table3");
}

我在这篇博客文章中发现了这种方法:Easy Integration Testing With Testcontainers

xienkqul

xienkqul2#

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

@RunWith(SpringRunner.class)
@DataJpaTest
public class MyTest { 
//...
}

使用Junit 5:

@DataJpaTest
public class MyTest { 
//...
}
6ovsh4lw

6ovsh4lw3#

您可以在测试方法上使用@Transactional,这样,每个测试方法都将在自己的事务括号内运行,并在下一个测试方法运行之前回滚。
当然,只有在您不使用手动事务管理的情况下,这才有效,并且它依赖于某些Sping Boot 自动配置魔法,因此它可能不适用于每个用例,但它通常是一种高性能且非常简单的隔离测试用例的方法。

6yt4nkrj

6yt4nkrj4#

我认为这是PostgreSQL最有效的方法。你可以为其他数据库做同样的事情。只要找到如何重新启动表序列并执行它

@Autowired
private JdbcTemplate jdbcTemplate;

@AfterEach
public void execute() {
    jdbcTemplate.execute("TRUNCATE TABLE users" );
    jdbcTemplate.execute("ALTER SEQUENCE users_id_seq RESTART");
}
dz6r00yl

dz6r00yl5#

我个人的偏好是:

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扩展类,并在构造函数中设置DataSource。

public class Test extends NamedParameterJdbcDaoSupport

public Test(DataSource dataSource)
{
    setDataSource(dataSource);
}

相关问题