我在让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中的SpringListener
和Wordspec
来构造测试
并做断言。
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
得到应用和尊重吗?
答案 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
或您使用的任何其他规范基类(使用实际的您可以注释的方法。