首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >MockK测试成员函数获取NullPointerException

MockK测试成员函数获取NullPointerException
EN

Stack Overflow用户
提问于 2022-08-11 04:47:51
回答 1查看 159关注 0票数 0

测试中的类如下所示:

代码语言:javascript
复制
class State(pivate val repo){
    val values = listOf<Int>()
    fun update() {
        values = repo.generateValues() // <-line 375
    }
}

单元测试看起来像:

代码语言:javascript
复制
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
private class StateTest {
    @MockK(relaxed = true) private lateinit var mockedRepo: Repo
    @BeforeAll
    fun config() {
        MockKAnnotations.init(this)
    }

    @BeforeEach
    fun setup() {
        clearAllMocks()
        unmockkAll()
    }

    @Test
    fun `invoke update`() {
        val state = mockk<State>(relaxed = true)

        every { state.repo } answers { mockedRepo }
        every { mockedRepo.generateValues() } returns listOf(1,2,3)
        every { state.update() } answers { callOriginal() }

        state.update()
        Assertions.assertTrue(state.values.size > 0)
    }
}

运行测试,将抛出一个NullPointerException:

代码语言:javascript
复制
java.lang.NullPointerException
    at com.name.someapp.someservice.State.update(State.kt:375)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at io.mockk.proxy.jvm.advice.MethodCall.call(MethodCall.kt:14)
    at io.mockk.proxy.jvm.advice.SelfCallEliminatorCallable.call(SelfCallEliminatorCallable.kt:14)
    at io.mockk.impl.instantiation.JvmMockFactoryHelper.handleOriginalCall(JvmMockFactoryHelper.kt:95)
    at io.mockk.impl.instantiation.JvmMockFactoryHelper.access$handleOriginalCall(JvmMockFactoryHelper.kt:18)
    at io.mockk.impl.instantiation.JvmMockFactoryHelper$mockHandler$1$invocation$$inlined$stdFunctions$lambda$1.invoke(JvmMockFactoryHelper.kt:27)
    at io.mockk.impl.stub.MockKStub$handleInvocation$originalPlusToString$1.invoke(MockKStub.kt:230)
    at io.mockk.MockKAnswerScope.callOriginal(API.kt:2205)
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-08-11 09:31:40

获得NullPointerException的原因是,fun update()不调用getRepo() (您已经对其进行了嘲弄),而是直接使用支持字段repo。(您可以通过将Kotlin源代码编译为字节码并在IntelliJ的思想中将其反编译为Java来看到这一点。)这在kotlinlang.org上也有记录。

JVM上的I:对带有默认getter和setter的私有属性的访问进行了优化,以避免函数调用开销。

正如sidgate在评论中所说,答案是创建一个真实的(而不是模拟的) State实例,并将模拟回购传递给它的构造函数:

代码语言:javascript
复制
val state = State(mockRepo)

这是一种模仿“被测试系统”的代码气味。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73315397

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档