在Spring上进行每次测试后重置数据库,而不使用DirtiesContext

时间:2018-02-09 21:08:55

标签: database spring integration-testing

我想知道在每次集成测试后是否有某种方法可以重置数据库没有 @DirtiesContext:

@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)

This works非常慢,因为每次测试都会重新加载Spring上下文。

我的测试是使用 MockMvc ,对API进行休息调用。像:

mockMvc.perform(put("/products/)
            .header("Content-Type", "application/json")
            .content(jsonPost))
            .andExpect(status().isOk())
            .andReturn();

那么,如果没有人工干预(创建和维护脚本来删除和创建表),Spring框架会提供一些替代方案吗?

3 个答案:

答案 0 :(得分:1)

在简单的情况下,将每个测试类注释为@Transactional,并且事务管理器将在每个@Test方法之后进行回滚。获取更多信息reading this

答案 1 :(得分:1)

您可以通过执行以下操作来清理所需的表:

  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

答案 2 :(得分:0)

我参加聚会有点晚了,但是我遇到了同样的问题。我使用一个嵌入式H2作为测试数据库,继承了我继承的应用程序中的所有单元测试(可以将其视为集成测试),大约需要35分钟才能完成。所有由@DirtiesContext注释的测试类,通常是方法级别。

因此,每种方法的数据库都被破坏并重新创建。这需要时间。 通过删除肮脏的注释并在@Before方法中使用数据库截断类,我现在大约在4分钟内运行了完整的测试套件。 如果您在Spring上下文中除了JPA东西(不是由实体管理器处理)之外还有其他东西应该在测试之间删除,则必须明确地做到这一点。

如果愿意,我可以共享DB截断类,但这只是使用JPA元模型来查找要截断的表。在H2中,截断似乎非常有效。可以配置基于视图而不是表的实体的例外。

要简化截断操作,请在截断之前关闭参照完整性,并在完成后将其重新打开。