kotlin - 使用 MockK 和 Kotlin 在 @SpringBootTest 中出现 UninitializedPropertyAccessException 的原因是什么?
问题描述
我正在尝试将 MockK 1.10.2 与 Kotlin 1.4.10 和 @SpringBootTest (Spring Boot 2.2.2.RELEASE) 一起使用,但由于
OpenJDK 64-Bit Server VM warning: Sharing is only supported for boot loader classes because bootstrap classpath has been appended
2020-11-05 15:00:37.878 WARN --- [ main] i.m.p.j.t.InliningClassTransformer : Failed to transform class java/lang/Object
java.lang.IllegalArgumentException: Unsupported class file major version 59
at net.bytebuddy.jar.asm.ClassReader.<init>(ClassReader.java:195)
at net.bytebuddy.jar.asm.ClassReader.<init>(ClassReader.java:176)
at net.bytebuddy.jar.asm.ClassReader.<init>(ClassReader.java:162)
at net.bytebuddy.utility.OpenedClassReader.of(OpenedClassReader.java:86)
at net.bytebuddy.dynamic.scaffold.TypeWriter$Default$ForInlining.create(TypeWriter.java:3394)
at net.bytebuddy.dynamic.scaffold.TypeWriter$Default.make(TypeWriter.java:1933)
at net.bytebuddy.dynamic.scaffold.inline.RedefinitionDynamicTypeBuilder.make(RedefinitionDynamicTypeBuilder.java:217)
at net.bytebuddy.dynamic.scaffold.inline.AbstractInliningDynamicTypeBuilder.make(AbstractInliningDynamicTypeBuilder.java:120)
at net.bytebuddy.dynamic.DynamicType$Builder$AbstractBase.make(DynamicType.java:3404)
at io.mockk.proxy.jvm.transformation.InliningClassTransformer.transform(InliningClassTransformer.kt:77)
at java.instrument/java.lang.instrument.ClassFileTransformer.transform(ClassFileTransformer.java:246)
at java.instrument/sun.instrument.TransformerManager.transform(TransformerManager.java:188)
at java.instrument/sun.instrument.InstrumentationImpl.transform(InstrumentationImpl.java:563)
at java.instrument/sun.instrument.InstrumentationImpl.retransformClasses0(Native Method)
at java.instrument/sun.instrument.InstrumentationImpl.retransformClasses(InstrumentationImpl.java:167)
at io.mockk.proxy.jvm.transformation.JvmInlineInstrumentation.retransform(JvmInlineInstrumentation.kt:28)
at io.mockk.proxy.common.transformation.RetransformInlineInstrumnetation$execute$1.invoke(RetransformInlineInstrumnetation.kt:19)
at io.mockk.proxy.common.transformation.RetransformInlineInstrumnetation$execute$1.invoke(RetransformInlineInstrumnetation.kt:6)
at io.mockk.proxy.common.transformation.ClassTransformationSpecMap.applyTransformation(ClassTransformationSpecMap.kt:41)
at io.mockk.proxy.common.transformation.RetransformInlineInstrumnetation.execute(RetransformInlineInstrumnetation.kt:16)
at io.mockk.proxy.jvm.ProxyMaker.inline(ProxyMaker.kt:88)
at io.mockk.proxy.jvm.ProxyMaker.proxy(ProxyMaker.kt:30)
kotlin.UninitializedPropertyAccessException: lateinit property taService has not been initialized
例外。(如果我使用 tmpService 也会发生同样的情况。导入的服务与测试类位于相同还是不同的包中都没有关系。)
正如您从我的测试类的代码中看到的那样,我已经玩了很多,但到目前为止没有任何成功。
package com.xxx.emr.tm
import com.xxx.data.emr.model.PatientAssignment
import com.xxx.data.tm.TMPService
import com.xxx.data.tm.model.MyType
import com.xxx.data.tm.model.MyTypeCode
import com.xxx.data.tm.model.UserAction
import com.xxx.emr.service.model.AuthenticatedUser
import io.mockk.every
import io.mockk.impl.annotations.InjectMockKs
import io.mockk.impl.annotations.SpyK
import io.mockk.junit5.MockKExtension
import io.mockk.mockk
import io.mockk.mockkObject
import io.mockk.verify
import org.junit.Test
import org.junit.jupiter.api.extension.ExtendWith
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.context.SpringBootTest
@ExtendWith(SpringExtension::class, MockKExtension::class)
@SpringBootTest // (classes = [com.xxx.emr.service.MyServiceSpringBoot::class])
// @RunWith(SpringJUnit4ClassRunner::class)
// @ActiveProfiles("test")
// @EnableAutoConfiguration
// @AutoConfigureMockMvc
class MyTest {
// (
// val tmpService: TMPService,
// val taService: TaService
// )
// @InjectMockKs
// @Autowired
// @SpyK
@MockK
private lateinit var tmpService: TMPService
@InjectMockKs
@Autowired
private lateinit var taService: TaService
@Test
fun assignAToB() {
MockKAnnotations.init(this, relaxUnitFun = true)
val vId = "xxx"
val authUser: AuthenticatedUser = AuthenticatedUser.mockedUser()
val userAction = UserAction(
userId = "user_id",
actionCode = ActionType.GET_IT,
sessionId = "sessionId"
)
val xxx = MyType(
MyTypeCode.ABC.value,
MyTypeCode.ABC.name,
)
val actionResult = UserActionResult(hashMapOf("success" to true))
// every { tmpService.getXxx(any()) } returns xxx
verify( exactly = 1 ) {
tmpService.doSomething(any(), any(), any())
}
verify( exactly = 1 ) {
taService.dowhatYouWant(„vId", authUser, userAction)
}
}
自动装配不起作用......那我的错是什么?我怎样才能让测试运行呢?
解决方案
我认为你应该首先初始化你的模拟,例如在你的测试文件中添加这个:
@org.springframework.test.context.event.annotation.BeforeTestMethod
fun initMocks() {
org.mockito.MockitoAnnotations.initMocks(this)
}
我在另一个线程上创建了一篇关于如何设置单元测试的帖子,与您的要求相当: https ://stackoverflow.com/a/64669499/7919904
推荐阅读
- php - php类中的变量问题
- url - 您能否拥有来自不同主机的具有不同 tld(.com, .uk, ...) 的同一网站,而仅托管在一台主机上?
- c++ - 如何正确配置 AcquireCredentialsHandleA
- java - 查找 .gif 文件的尺寸
- mongodb - 如何过滤子数组但保留根内容?
- mysql - 如何在不覆盖原始表的情况下将新表附加到原始表中?
- visual-studio-code - VSCode 如何 _enable_ Regex 通过命令查找,而不是“切换”
- typescript - 打字稿错误?具有“参数'x'隐式具有'任何'类型”错误的正确类型数组方法
- oracle - AWS DMS - Oracle 到 PG RDS 完全加载操作错误 - 无法从 csv 文件加载数据
- vba - 打印word文档时如何隐藏ActiveX命令按钮?