【问题标题】:How to execute sql script before and after each test method如何在每个测试方法之前和之后执行sql脚本
【发布时间】:2020-10-25 21:55:49
【问题描述】:

spring中有一个@Sql注解,允许在测试方法前后执行sql代码:

@Test
@Sql("init.sql")
@Sql(scripts = "clean.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD)
public void someTest()
{
}

但是,我有几种测试方法,我想提供与上述测试相同的干净环境,并且我不想为每个测试重复相同的 @Sql 注释。如何为所有方法做一次?例如:

// JPA and Spring other test annotations
@Sql("init.sql")
@Sql(scripts = "clean.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD)
public class TestClass
{
  // init.sql executed before every test, clean.sql executed after every test
}

【问题讨论】:

    标签: java spring spring-boot jpa junit


    【解决方案1】:

    确实,当您将@Sql 放在class 上时,sql 脚本将在该类中定义的每个测试之前和之后执行,更具体地说,在@Before 之前和@After 方法之后.所以,

    // JPA and Spring other test annotations
    @Sql("init.sql")
    @Sql(scripts = "clean.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD)
    public class TestClass
    {
      // init.sql executed before every test, clean.sql executed after every test
    }
    

    将根据@Sql 定义工作:

    @Target({ElementType.TYPE, ElementType.METHOD})
    /// other annotations
    public @interface Sql {
       //
    }
    

    【讨论】:

      【解决方案2】:

      如果我的理解是正确的,你是想执行一个init脚本把DB置于某个状态,然后在每个测试方法之前确保DB回到那个状态,对吧?

      那么最简单的解决方案是使用@Transactional。默认情况下,Spring Boot 会自动回滚 @Transactional-annotated 测试的测试事务,从而将 DB 重置为原始状态。

      不过,有两个缺点应该考虑:

      1. @Transactional 表示将存在一个跨越测试方法的整个执行的事务,测试的服务方法通常会加入该事务。因此,不能依靠测试本身来验证生产代码中事务边界的正确性(例如,LazyInitializationExceptions 可能被这个“外部”事务覆盖)
      2. 除非必要,否则不会刷新持久性上下文,这意味着某些问题(例如违反数据库约束)不会出现。我倾向于使用最后机会冲洗来解决这个问题,如下所示:
        @After
        public void flushContext() {
          if (TransactionSynchronizationManager.isActualTransactionActive()) {
            entityManager.flush();
          }
        }
      

      【讨论】:

      • 回答第一个问题:是的,这正是我想要实现的。我使用@DataJpaTest,所以无论如何都会使用@Transactional。我想运行 init 和 clear 脚本的原因是因为无法回滚的序列,所以在 init.sql 和 clean.sql 中我删除序列并重新创建它们从而具有完全干净的状态。感谢您对@Transactional 的第一条评论非常好。
      猜你喜欢
      • 2016-01-01
      • 2021-09-11
      • 2020-07-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-23
      • 2023-03-26
      • 2014-05-02
      相关资源
      最近更新 更多