簡體   English   中英

mockk,如何為 MutableMap 使用插槽<String, String>

[英]mockk, how to use slot for MutableMap<String, String>

使用模擬 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)
}

}

您需要使用capture (請參閱Mockk 的捕獲部分)。

所以對於你的情況capture(mapSlot)應該有效。

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

在嘗試模擬復雜的代碼之前,最好先學習更簡單的示例。

這是一個使用 mockk 模擬object上的私有調用的工作示例。

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")

請嘗試修改值以檢查不同的行為。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM