android Mockk在Kotlin中模拟私有属性

6fe3ivhb  于 2023-03-27  发布在  Android
关注(0)|答案(2)|浏览(170)

我有一个带私有字段的简单类。

class EmployeeData {

    private var employeeAge: Int = 0
    
    fun getAge(): Int {
        return 1 + employeeAge
    }
}

我试图测试这个私人employeeAge与以下从官方文档

@Test
fun testPrivateAge() {

    val mock = spyk(EmployeeData())

    every {
        mock getProperty "employeeAge"
    } propertyType Int::class answers { fieldValue + 6 }
    every {
        mock setProperty "employeeAge" value any<Int>()
    } propertyType Int::class answers  { fieldValue += value }

    every { mock getProperty "employeeAge" } returns 33
    every { mock setProperty "employeeAge" value less(5) } just Runs

    assertEquals(10,mock.getAge())
}

我收到了来自MockK的例外

io.mockk.MockKException: Missing calls inside every { ... } block.

at io.mockk.impl.recording.states.StubbingState.checkMissingCalls(StubbingState.kt:14)
at io.mockk.impl.recording.states.StubbingState.recordingDone(StubbingState.kt:8)

官方文档建议对私有财产使用这种技术,但对我来说它不起作用,我使用的是MockK的最新版本,它是v1.10.0
虽然对于私有方法来说,它的工作原理就像一个魅力。我能够在这个逻辑中测试私有方法。

qxsslcnc

qxsslcnc1#

这是一些Kotlin优化的一个问题。根据MockK作者“简要说明。模拟私有属性几乎是不可能的,因为它们没有附加getter方法。这是一种Kotlin优化,解决方案是重大变化。”
更多信息可以在这两个Github问题上找到:

5ssjco0h

5ssjco0h2#

可以使用Java反射为SUT设置私有属性。

val field = EmployeeData::class.java.getDeclaredField("employeeAge")
field.isAccessible = true
field.set(employeeData, 33)

assertEquals(34, employeeData.getAge())

相关问题