Котлинтест с 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 или любой другой базовый класс спецификации, который вы используете, который использует реальные методы, которые вы можете аннотировать.

Другие вопросы по тегам