mockk,如何为 MutableMap<String, String> 使用插槽
mockk, how to use slot for MutableMap<String, String>
使用 mockk 1.9.3
有待验证的功能
class EventLogger 私有构造函数()
fun logUserEvent(eventName: String?, eventParamMap: MutableMap<String, String>?) {
......
internaLogEventImpl(eventName, eventParamMap)
}
internal fun internaLogEventImpl(eventName: String?, customParams: MutableMap?) {
……
}
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?
找到:CapturingSlot>
在下面尝试时:
class 测试K {
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's Capturing section)。
所以对于你的情况 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")
.
请尝试修改值以检查不同的行为。
使用 mockk 1.9.3
有待验证的功能
class EventLogger 私有构造函数()
fun logUserEvent(eventName: String?, eventParamMap: MutableMap<String, String>?) {
......
internaLogEventImpl(eventName, eventParamMap)
}
internal fun internaLogEventImpl(eventName: String?, customParams: MutableMap
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
class 测试K {
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's Capturing section)。
所以对于你的情况 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")
.
请尝试修改值以检查不同的行为。