【问题标题】:What is the reason for an UninitializedPropertyAccessException in @SpringBootTest with MockK and Kotlin?使用 MockK 和 Kotlin 在 @SpringBootTest 中出现 UninitializedPropertyAccessException 的原因是什么?
【发布时间】:2021-02-17 01:56:37
【问题描述】:

我正在尝试将 MockK 1.10.2 与 Kotlin 1.4.10 和 @SpringBootTest (Spring Boot 2.2.2.RELEASE) 一起使用,但由于 a

而我无法运行它
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)
    }
}

自动装配不起作用...那我的错是什么?我怎样才能让测试运行?

【问题讨论】:

    标签: kotlin spring-boot-test mockk


    【解决方案1】:

    我认为你应该首先初始化你的模拟,例如在你的测试文件中添加这个:

    @org.springframework.test.context.event.annotation.BeforeTestMethod
    fun initMocks() {
        org.mockito.MockitoAnnotations.initMocks(this)
    }
    

    我在另一个线程上创建了一篇关于如何设置单元测试的帖子,与您的要求相当: https://stackoverflow.com/a/64669499/7919904

    【讨论】:

    • 我试过这个没有成功。我也有:java.lang.IllegalArgumentException: Unsupported class file major version 59
    • 好吧,你在用 MockK,我以为你在用 Mockito……也许你应该试试 Mockito?
    • 根据 MockK 文档,在 MockK 中初始化模拟应该以这种方式完成:MockKAnnotations.init(this, RelaxUnitFun = true)
    • 没有成功。 MockK 1.10.2 是否与 Java 15(在语言级别 11 上运行)不兼容? (考虑异常堆栈跟踪的第一行。)
    • 为什么使用 Java 15? 11 是当前的 LTS,15 永远不会是 LTS :)
    猜你喜欢
    • 2017-11-16
    • 2018-01-12
    • 2021-02-01
    • 2018-08-31
    • 1970-01-01
    • 1970-01-01
    • 2010-11-06
    • 1970-01-01
    • 2019-05-01
    相关资源
    最近更新 更多