Как заполнить базу данных только один раз перед методами @Test в тесте spring?
Следующим тестовым тестированием spring уровня сервиса с junit4 является:
Как вызвать script, который заполняет базу данных только один раз перед всеми методами @Test:
Я хочу выполнить это один раз перед всеми @Tests:
JdbcTestUtils.executeSqlScript(jdbcTemplate(), new FileSystemResource(
"src/main/resources/sql/mysql/javahelp-insert.sql"), false);
Я попытался использовать @PostConstruct в моем классе GenericServiceTest (расширенный тестовыми классами).
Оказалось, что @PostConstruct вызывается каждый раз перед каждым методом @Test. Интересно, что даже любые методы, аннотированные @Autowired из GenericServiceTest, вызывается перед каждым методом @Test.
Я не хочу заполнять базу данных перед каждым тестовым классом, но только один раз при запуске spring -test.
Как выполнить вышеописанный метод только один раз перед всеми методами @Test с помощью spring рамки тестирования и junit4?
Спасибо!
Ответы
Ответ 1
Использование поддержки встроенных баз данных Springs
<jdbc:embedded-database id="dataSource">
<jdbc:script location="classpath:myScript.sql"/>
<jdbc:script location="classpath:otherScript.sql"/>
</jdbc:embedded-database>
или Springs Инициализировать поддержку базы данных
<jdbc:initialize-database data-source="dataSource">
<jdbc:script location="classpath:myScript.sql"/>
<jdbc:script location="classpath:otherScript.sql"/>
</jdbc:initialize-database>
@See http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/jdbc.html#jdbc-embedded-database-support
Ответ 2
Основываясь на ответе Альфредоса, это способ ввода информации о базе данных без вызова встроенной базы данных по умолчанию script. Например, это может быть полезно, когда вы хотите автоматическую сборку DDL для вас - по крайней мере, в тестах.
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"/applicationContext.xml"})
public class TestClass {
@Autowired
private ApplicationContext ctx;
private JdbcTemplate template;
@Autowired
public void setDataSource(DataSource dataSource) {
template = new JdbcTemplate(dataSource);
}
private static boolean isInitialized = false;
@Before
public void runOnce() {
if (isInitialized) return;
System.out.println("Initializing database");
String script = "classpath:script.sql";
Resource resource = ctx.getResource(script);
JdbcTestUtils.executeSqlScript(template, resource, true);
isInitialized = true;
}
}
Таким образом, метод runOnce()
вызывается один раз и только один раз для тестового прогона. Если вы сделаете isInitialized
поле экземпляра (нестатического), метод будет вызываться перед каждым тестом. Таким образом, вы можете сбросить/повторно заполнить таблицы, если необходимо, перед каждым испытанием.
Обратите внимание, что это по-прежнему довольно быстрое и грязное решение, и разумный способ обработки базы данных соответствует ответу Ральфа.
Ответ 3
Если вы используете Spring Boot, вы можете указать несколько скриптов для запуска перед тестированием через
spring.datasource.data=classpath:accounts.sql, classpath:books.sql, classpath:reviews.sql
Ответ 4
Пример, основанный на примере Майка Адлерса, но для JUnit 5 и с использованием ResourceDatabasePopulator, упомянутым Tugdual.
Тестовые классы создаются один раз для каждого метода тестирования. Так что если вы хотите заполнить только один раз, вам нужно как-то справиться с этим. Здесь это делается с помощью статической переменной.
@Autowired
private DataSource dataSource;
private static boolean isInitialized;
@BeforeEach // JUnit 5
void initDatabase() {
if(!isInitialized) { // init only once
ResourceDatabasePopulator populator = new ResourceDatabasePopulator();
populator.addScript(new ClassPathResource("/sql/myscript.sql")));
populator.execute(dataSource);
isInitialized = true;
}
}