Mockk在Kotlin中模拟私有属性

10

我有一个简单的类,其中包含一个私有字段。

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

然而,对于私有方法,它却像魔术一样运行良好。我能够在这个逻辑中测试私有方法。


这个解决方案可能有效:https://dev59.com/krfna4cB1Zd3GeqPvZV2#65786951 - Interkot
也看到了这个问题! - Mitch Thornton
3个回答

5

1

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

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

assertEquals(34, employeeData.getAge())

0
嗯,我有同样的问题,看起来它仍然没有解决 - 不过我找到了一个变通方法,通过明确定义属性的setter和getter方法,并将值保存在私有字段中。我个人认为这很丑陋,我不打算使用这种方法(而是跳过单元测试):例如:
private var _myProperty = "Value"
private var myProperty: String
    get() {
        return _myProperty
    }
    set(value) {
        _myProperty = value
    }

测试:
every { sut getProperty "myProperty" } propertyType String::class answers { "some test value" }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接