Как выполнить @Sql перед методом @Before

Я пытаюсь объединить следующие аннотации:

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 выполняется после сценария "dml-parametertro.sql" в аннотации @Sql.

Правильно ли это делать?

Для решения этой проблемы я использую @After вместо @Before, но я бы хотел удалить таблицы до выполнения теста, а не после.

Я не хотел бы использовать @SqlConfig. Я не использую трансакционную область на уровне теста, поэтому мне нужно чистить свои таблицы в каждом методе тестирования. Если каждый метод тестирования должен очистить таблицы, я хотел бы сделать это в методе @Before. Я не хотел бы делать это в каждом методе тестирования с @SqlConfig. Я думаю, что поведение @Sql, которое будет выполнено раньше, чем @Before, неправильное.

1 ответ

По умолчанию любые сценарии SQL выполняются через @Sql будет выполнен до любого @Before методы. Таким образом, поведение, которое вы испытываете, является правильным, но вы можете изменить фазу выполнения с помощью executionPhase приписывать @Sql (см. пример ниже).

Если вы хотите выполнить несколько сценариев, это также возможно с помощью @Sql,

Так что если у вас есть сценарий очистки с именем clean-parametro.sql который удаляет из PARAMETRO таблицу, вы можете аннотировать ваш метод тестирования, как показано ниже (вместо вызова JdbcTestUtils.deleteFromTables() в вашем @Before метод).

@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() { /* ... */ }

Или использовать @SqlGroup в качестве контейнера на Java 6 или Java 7:

@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() { /* ... */ }

Я надеюсь, что это проясняет для вас вещи!

Ура,

Сэм (автор Spring TestContext Framework)


Заметки:

  • AFTER_TEST_METHOD статически импортируется из ExecutionPhase
  • ISOLATED статически импортируется из TransactionMode
Другие вопросы по тегам