【问题标题】:How to execute @Sql before a @Before method如何在@Before方法之前执行@Sql
【发布时间】:2015-01-23 11:19:35
【问题描述】:

我正在尝试结合以下注释:

org.springframework.test.context.jdbc.Sqlorg.junit.Before

喜欢下面的代码:

@Test
@Sql(scripts = "dml-parametro.sql")
public void testData(){
    Iterable<Parametro> parametros = parametroService.findAll();
    List<Parametro> parametrosList = Lists.newArrayList(parametros);

    Assert.assertThat(parametrosList.size(), Is.is(1));
}

@Before
public void beforeMethod() {
    JdbcTestUtils.deleteFromTables(jdbcTemplate, "PARAMETRO");
}

方法@Before中的代码在@Sql注解中的脚本“dml-parametro.sql”之后运行。

这样做是否正确?

为了解决这个问题,我使用 @After 而不是 @Before,但我想在测试执行之前 cdelete 表,而不是之后。

我不想使用@SqlConfig。我没有在测试级别使用跨域范围,所以我需要在每种测试方法中清理我的表。如果每个测试方法都需要清理表,我想在 @Before 方法中执行此操作。我不想在每个使用@SqlConfig 的测试方法中都这样做。我认为@Sql 的行为比@Before 更早执行是错误的。

【问题讨论】:

    标签: spring spring-test


    【解决方案1】:

    默认情况下,通过@Sql 执行的任何 SQL 脚本将在任何@Before 方法之前执行。所以您遇到的行为是正确的,但您可以通过@Sql 中的executionPhase 属性更改执行阶段(参见下面的示例)。

    如果您想执行多个脚本,也可以通过@Sql

    因此,如果您有一个名为 clean-parametro.sql 的清理脚本从 PARAMETRO 表中删除,您可以如下注释您的测试方法(而不是在您的 @Before 方法中调用 JdbcTestUtils.deleteFromTables())。

    @Test
    @Sql({"dml-parametro.sql", "clean-parametro.sql"})
    public void test() { /* ... */ }
    

    当然,如果dml-parametro.sql 将值插入到PARAMETRO 表中,那么在清理脚本中立即删除这些值可能没有意义。

    请注意@Sql@SqlConfig 为脚本执行提供了多级配置。

    例如,如果您想在测试前创建表并在测试后清理,您可以在 Java 8 上执行以下操作:

    @Test
    @Sql("create-tables.sql")
    @Sql(scripts = "clean-up.sql", executionPhase = AFTER_TEST_METHOD)
    public void test() { /* ... */ }
    

    或者在 Java 6 或 Java 7 上使用 @SqlGroup 作为容器:

    @Test
    @SqlGroup({
        @Sql("create-tables.sql"),
        @Sql(scripts = "clean-up.sql", executionPhase = AFTER_TEST_METHOD)
    })
    public void test() { /* ... */ }
    

    如果您的测试是@Transactional,并且您想清理已提交的数据库状态,您可以指示 Spring 在新事务中执行清理 SQL 脚本,如下所示:

    @Test
    @Sql("insert-test-data.sql")
    @Sql(
      scripts = "clean-up.sql",
      executionPhase = AFTER_TEST_METHOD,
      config = @SqlConfig(transactionMode = ISOLATED)
    )
    public void test() { /* ... */ }
    

    我希望这可以为您澄清事情!

    干杯,

    Sam (Spring TestContext 框架的作者)


    注意事项:

    • AFTER_TEST_METHOD 是从 ExecutionPhase 静态导入的
    • ISOLATED 是从 TransactionMode 静态导入的

    【讨论】:

    • 我有一个用@Sql 注释的抽象类,它运行一些脚本,以及它的一个子类,它也用@Sql 注释。当我运行spring boot 1.2时,一切都按预期工作->抽象类脚本在子类scipts之前运行。但是一旦我升级到 Spring Boot 1.3,子类@Sql 开始覆盖抽象父类的@Sql,因此父类脚本永远不会运行。我现在不知道该怎么办:/
    • 我为此创建了一个问题,在这里可以找到:stackoverflow.com/questions/39296329/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-10-25
    • 2019-10-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-05
    • 2013-06-03
    相关资源
    最近更新 更多