0

使用模拟 1.9.3

有待验证的功能

类 EventLogger 私有构造函数()

fun logUserEvent(eventName: String?, eventParamMap: MutableMap<String, String>?) {
   ......
    internaLogEventImpl(eventName, eventParamMap)
}

内部乐趣 internaLogEventImpl(eventName: String?, customParams: MutableMap<String, String>?) { ...... }

companion object {
     @Volatile
     private var sEventLoggerSingleton: EventLogger? = null

     @JvmStatic
    val instance: EventLogger
        get() {
            if (sEventLoggerSingleton == null) {
                sEventLoggerSingleton = EventLogger()
            }
            return sEventLoggerSingleton!!
        }
}

在每个 {eventLogger.internaLogEventImpl(any(), mapSlot)} 处得到编译器错误 在此处输入图像描述

类型不匹配。必需:MutableMap<String, String>? 发现: CapturingSlot<MutableMap<String, String>> 在下面尝试时:

类TestK {

lateinit var eventLogger: EventLogger
lateinit var application: Application

val mapSlot = slot<MutableMap<String, String>>()

@Before
fun setUp() {
    application = ApplicationProvider.getApplicationContext<Application>()
    eventLogger = mockk.spyk(EventLogger.instance)
    ReflectionHelpers.setStaticField(EventLogger::class.java, "sEventLoggerSingleton", eventLogger)
}

@After
fun cleanUp() {
    ReflectionHelpers.setStaticField(EventLogger::class.java, "sEventLoggerSingleton", null)
}

@Test
fun logNotificationStatusChange_with_enabled_WhenCalled_ShouldLog() {

    val testMap = hashMapOf("action" to "open")

    every {eventLogger.internaLogEventImpl(any(), mapSlot)} answers {
        println(mapSlot.captured)
        assert(mapSlot.captured["action"] == "open")
    }
    eventLogger.logUserEvent("test_event", testMap)
}

}

4

1 回答 1

2

您需要使用capture(参见Mockk 的捕获部分)。

所以对于你的情况capture(mapSlot)应该有效。

eventLogger.internaLogEventImpl(any(), capture(mapSlot))

在尝试模拟复杂代码之前,最好先学习更简单的示例。

这是一个在objectwith mockk 上模拟私人通话的工作示例。

object MyLogger {
    fun logUserEvent(event: String?, map: MutableMap<String, String>?) {
        // turns the event string into an uppercase string.
        internaLogEventImpl(event?.toUpperCase(), map)
    }

    private fun internaLogEventImpl(event: String?, map: MutableMap<String, String>?): Unit =
        throw Exception("real implementation")
}

如何测试和模拟内部函数,这样我们就不会抛出异常。

@Test
fun `test logger internal`() {
    val expectedMap = mutableMapOf("a" to "b")
    val expectedEvent = "EVENT"

    val mock = spyk(MyLogger, recordPrivateCalls = true)
    justRun { mock["internaLogEventImpl"](expectedEvent, expectedMap) }
    // or justRun { mock["internaLogEventImpl"](any<String>(), any<MutableMap<String, String>>()) }

    mock.logUserEvent("event", expectedMap)

    verify { mock["internaLogEventImpl"](expectedEvent, expectedMap) }
}

这里logUserEvent调用真实实现,internaLogEventImpl调用模拟实现。

如果justRun { mock["internaLogEventImpl"](expectedEvent, expectedMap) }没有被调用(或者因为参数不匹配而出错),真正的实现将被调用。在这里它会抛出Exception("real implementation").

请尝试修改值以检查不同的行为。

于 2021-07-13T00:39:53.197 回答