Котлинтест с Spring Test, @Transactional не работает / не применяется
У меня проблема с тем, чтобы Spring Boot 2.0.5 хорошо работал с Kotlintest 3.1.10.
Я сделал тестовый проект, иллюстрирующий мою проблему. Проект представляет собой приложение Spring Boot 2 с двумя сущностями, ShoppingOrder и OrderLine (чтобы быть полностью невообразимым).
Также есть тестовый пример ShoppingOrderSpec
который просто проверяет отображение, сохраняя и получая Заказ.
Тестовый случай настроен так:
@ExtendWith(SpringExtension::class)
@Transactional
@SpringBootTest
class ShoppingOrderSpec : WordSpec() {
override fun listeners() = listOf(SpringListener)
Тестовый пример использует SpringExtension от Spring для подключения к движку JUnit 5. Он также использует SpringListener
а также Wordspec
от Kotlintest, чтобы структурировать тесты и сделать утверждения.
SpringListener
правильно автоматически связывает зависимости, но как-то транзакция не создается.
Запуск тестового примера дает следующую трассировку стека:
2018-10-12 10: 54: 14.329 ИНФОРМАЦИЯ 59374 --- [intest-engine-0] com.example.demo.ShoppingOrderSpec: Запуск ShoppingOrderSpec через 4.478 секунд (JVM работает в течение 7.421) org.hibernate.LazyInitializationException: не удалось выполнить лениво инициализировать коллекцию ролей: com.example.demo.ShoppingOrder.lines, не удалось инициализировать прокси - нет сеанса в org.hibernate.collection.internal.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:582) ... в com.example.demo.ShoppingOrderSpec$1$1.invoke(ShoppingOrderSpec.kt:35) на com.example.demo.ShoppingOrderSpec$1$1.invoke(ShoppingOrderSpec.kt:19)
Итак, как-то org.springframework.transaction.annotation.Transactional
аннотация, похоже, не работает, так как удаление аннотации просто дает тот же ответ.
Кто-нибудь есть идеи, как получить @Transactional
применяется и уважается?
1 ответ
Вы не можете использовать расширения JUnit Jupiter с KotlinTest, так как это разные движки. Junit Jupiter - это реализация поверх Junit Platform, как и KotlinTest, но все, что написано специально для Jupiter, не будет работать с KotlinTest. Однако все, что написано для платформы Junit, должно работать.
К сожалению, выбор команды имен JUnit плохой, и поэтому люди думают, что JUnit Jupiter - это то же самое, что и платформа JUnit.
Во всяком случае, те,
@ExtendWith(SpringExtension::class)
@Transactional
@SpringBootTest
Расширения ничего не будут значить для KotlinTest, больше, чем для Spek или чего-то еще. ExtendWith
является конкретной аннотацией Юпитера, которая говорит ему использовать SpringExtension
учебный класс. Эквивалент KotlinTest является SpringListener
который вы уже подключили.
Я не уверен, если @SpringBootTest
будет поднят или нет весной. Поддержка может потребоваться добавить для этого в зависимости от того, что он делает.
Наконец, @Transactional работает путем создания прокси для методов, но, поскольку в более продвинутых средах тестирования, таких как KotlinTest, тестовые контейнеры - это не методы, а просто произвольные функции, они не смогут перехватывать.
Я думаю, что в этом случае вам может понадобиться создать правильный метод и аннотировать его, или попытаться использовать AnnotationSpec вместо StringSpec
или любой другой базовый класс спецификации, который вы используете, который использует реальные методы, которые вы можете аннотировать.