Как выполнить @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