Kotlintest使用Spring Test,@ Transactional无法正常工作/应用

时间:2018-10-12 09:24:26

标签: spring-boot spring-data-jpa kotlintest

我在让Spring Boot 2.0.5与Kotlintest 3.1.10配合使用时遇到问题。

我做了test project来说明我所遇到的问题。 该项目是Spring Boot 2应用程序 有两个实体ShoppingOrder和OrderLine(完全没有想象力)。

还有一个测试用例ShoppingOrderSpec,它只是通过存储和检索Order来测试映射。

测试用例的配置如下:

@ExtendWith(SpringExtension::class)
@Transactional
@SpringBootTest
class ShoppingOrderSpec : WordSpec() {
    override fun listeners() = listOf(SpringListener)

测试用例正在使用SpringExtension 通过Spring连接到JUnit 5引擎。它还使用Kotlintest中的SpringListenerWordspec来构造测试 并做断言。

SpringListener正确地自动关联了依赖关系,但是以某种方式未创建事务。

运行测试用例会给出以下堆栈跟踪:

2018-10-12 10:54:14.329信息59374 --- [intest-engine-0] com.example.demo.ShoppingOrderSpec:在4.478秒内启动ShoppingOrderSpec(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 个答案:

答案 0 :(得分:0)

您不能在KotlinTest中使用JUnit Jupiter扩展,因为它们是不同的引擎。与KotlinTest一样,Junit Jupiter是在Junit平台之上的实现,但是专门为Jupiter编写的任何内容均不适用于KotlinTest。但是,为Junit Platform编写的任何内容都应该可以工作。

不幸的是,JUnit团队的命名选择是糟糕的imo,因此人们认为JUnit Jupiter 与JUnit Platform是同一件事。

无论如何

@ExtendWith(SpringExtension::class)
@Transactional
@SpringBootTest

扩展对于KotlinTest而言并没有任何意义,对Spek或其他任何意义而言。 ExtendWith是特定于Jupiter的注释,告诉它使用SpringExtension类。 KotlinTest的等效项是SpringListener,您已经在其中进行了接线。

我不确定@SpringBootTest是否会被Spring接收。可能需要添加支持,具体取决于它的作用。

最后,@ Transactional通过在方法上创建代理来工作,但是由于在像KotlinTest这样的更高级的测试框架中,测试容器不是方法,而是任意函数,因此无法拦截。

我认为在这种情况下,您可能需要创建一个适当的方法并对其进行注释,或者尝试使用AnnotationSpec而不是StringSpec或您使用的任何其他规范基类(使用实际的您可以注释的方法。