spring 如何在@Before方法之前执行@Sql

r3i60tvu  于 2023-04-10  发布在  Spring
关注(0)|答案(1)|浏览(135)

我尝试合并以下注解:

  • org.springframework.test.context.jdbc.Sql
  • org.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之前执行的行为是错误的。

siv3szwd

siv3szwd1#

默认情况下,通过@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 Framework的作者)
备注:

  • AFTER_TEST_METHODExecutionPhase静态导入
  • ISOLATEDTransactionMode静态导入

相关问题