【问题标题】:Reset database after each test on Spring without using DirtiesContext在 Spring 上的每次测试后重置数据库而不使用 DirtiesContext
【发布时间】:2018-02-09 21:08:55
【问题描述】:

我想知道在每次集成测试后是否有某种方法可以重置数据库没有 @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 框架提供了一些替代方案吗?

【问题讨论】:

    标签: database spring integration-testing


    【解决方案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

    【讨论】:

    • 问题询问being without manual intervention
    【解决方案2】:

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

    【讨论】:

    • 谢谢!抱歉,但我没有提到我的测试是使用 MockMVC 进行休息调用。我认为这在这种情况下不起作用。
    【解决方案3】:

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

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

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

    为了使截断更容易,请在截断之前关闭引用完整性,并在完成后将其重新打开。

    【讨论】:

      猜你喜欢
      • 2013-11-08
      • 2019-01-01
      • 2019-08-29
      • 1970-01-01
      • 1970-01-01
      • 2012-12-29
      • 2019-01-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多