В моем проекте используется Spring, Hibernate ant JUnit 5. Каков наилучший подход к инициализации БД перед всеми тестами?
Вот как я устал это делать:
class DbCreatorService {
@Autowired
private Service1;
@Autowired
private Service2;
....
}
@ExtendWith(SpringExtension.class)
@ContextConfiguration(locations = "classpath:spring/applicationContext.xml")
@Transactional
class MyTest {
@BeforeAll
static void initDatabase(@Autowired DbCreatorService dbCreatorService ) {
dbCreatorService.initDB()
}
}
Когда я звоню sessionFactory.getCurrentSession() где-то в initDB(), я получаю: org.hibernate.HibernateException: Could not obtain transaction-synchronized Session for current thread. sessionFactory внедряется с помощью @Autowired.
он создает базу данных и вставляет данные в таблицы
Я обновил свой вопрос с более подробной информацией
Я делал это со встроенным H2 в тестовой области. У меня есть код с работы, чтобы показать вам. Завтра постараюсь написать ответ.
Сценарий базы данных, который удобен для тестирования и может быть легко настроен до и после каждого тестового примера.
Я использовал встроенную базу данных H2 в области тестирования с настройкой базы данных с помощью сценария SQL перед каждым тестовым случаем.
Во-первых, добавьте H2 в зависимость области тестирования от pom.xml (вы используете Maven, верно?).
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>test</scope>
</dependency>
Затем настройте класс тестов JUnit.
SampleTestClass.java
@SpringBootTest // Allows you to autowire beans on your test class
@AutoConfigureTestDatabase // Configures a database on test scope instead of your regular database config.
@RunWith(SpringRunner.class) // Runs test context with SpringRunner.class
@SqlGroup({ // Setups .sql files to be run on specific triggers. In this case, before each test method the script will be ran.
@Sql(executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD, scripts = "classpath:beforeTest.sql"),
})
@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD) // The spring application context will be considered "dirty" before each test method, and will be rebuilt. It means that
// your autowired beans will not carry any data between test cases.
public class SampleTestClass {
// write your test cases here...
}
@Before в своем тестовом классе. Этот метод будет запускаться перед каждым тестовым случаем.Спасибо за подробное объяснение, но мне нужен был способ инициализировать БД перед всеми методами тестирования, а не для каждого метода тестирования. Также я использую JUnit5 и только Spring, а не SpringBoot.
Извините за неправильное понимание ваших реквизитов. Тем не менее, я считаю, что вы все еще можете использовать некоторые из этих методов для настройки вашей БД для тестов. Если вам нужно инициализировать БД перед ВСЕМИ тестами, как вы сказали, аннотация JUnit @Before - ваш лучший выбор. Единственная разница между загрузкой Spring и Spring — это аннотации конфигурации контекста, и я полагаю, что вы уже разобрались с ними в своем коде.
Я использую @Before с флагом, поэтому я инициализирую БД только один раз, но это выглядит как взлом.
Использование before для общих настроек набора тестов — самое элегантное решение.
Была ли эта установка полезной? Вы нашли более элегантное решение?
Я добавил ответ с моим окончательным решением
Мои тесты только что читали из БД, и я хотел инициализировать БД только один раз перед всеми тестами. Мое окончательное решение:
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
@ExtendWith(SpringExtension.class)
@ContextConfiguration(locations = "classpath:spring/applicationContext.xml")
@Transactional
class MyTest {
@Autowired
private DbCreatorService dbCreatorService;
@BeforeAll
void initDatabase() {
dbCreatorService.initDB()
}
}
Как это работает, когда метод, отмеченный @BeforeAll, должен быть статическим?
Это работает из-за @TestInstance(TestInstance.Lifecycle.PER_CLASS) baeldung.com/java-beforeall-afterall-нестатический
Что делает метод initDB()? Инициализирует подключение к БД или подготавливает таблицы с данными перед тестами?