[英]Mockk with context receiver
我正在嘗試使用 Mockk 來模擬帶有上下文接收器的方法:
class MyClass {
// The method I'm going to mock
context(CallContext)
fun myMethod(a: Int) Int { a }
}
很難在單元測試中獲取 CallContext 的實例。 所以我希望我可以這樣寫一個單元測試:
/*
This should work, but I can't get the CallContext instance
with(callContextInstance) {
Every { mockedMyClass.myMethod(1) } returns 2
}
*/
// I hope a unit test can be written like this... But it won't compile now.
with(any<CallContext>) {
Every { mockedMyClass.myMethod(1) } returns 2
}
所以我該怎么做? 提前致謝。
在撰寫本文時,MockK不支持 context receivers ,並且可能要等到 context receivers 發布后才會支持——所以在 Kotlin 1.9 之后的某個時間,所以可能是在 2024 年)。
(上下文接收器被明確描述為尚未准備好生產。穩定版本將在 K2 發布之后發布,並且K2 beta 的目標是 Kotlin 1.9 ,計划於 2023 年 12 月發布。)
也就是說,如果有人想嘗試支持,那就堅持下去。MockK 是一個接受 PR 的社區支持的開源項目。
然而,在 MockK 完全支持上下文接收器之前有兩個障礙:
同時,您可以調整代碼以允許手動模擬。
首先,將MyClass
調整為一個開放類,或者引入一個新接口來描述您想要模擬的行為(接口代碼)。
/** Describe the API that [MyClass] will implement */
interface MyClassSpec {
context(CallContext)
fun myMethod(a: Int): Int
}
然后實現接口
/** Concrete implementation of [MyClassSpec] */
class MyClass: MyClassSpec {
context(CallContext)
override fun myMethod(a: Int): Int = a
}
現在在您的測試中,您可以通過創建一個實現MyClassSpec
的匿名對象來創建模擬 - 現在您有一個支持上下文接收器的模擬。
@Test
fun myTest() {
val myClassMock = object : MyClassSpec {
context(CallContext)
override fun myMethod(a: Int): Int = 123
}
}
如果我知道你到底想模擬什么,以下適用於 mockk 1.13.3:
interface CallContext
class MyClass {
context(CallContext)
fun myMethod(a: Int): Int = a
}
class ContextMockTest {
private val myClassMock: MyClass = mockk()
@Test
fun mockContextWorks() {
every {
with(any<CallContext>()) {
myClassMock.myMethod(any())
}
} returns 123
val context = object : CallContext { }
with(context) {
assertEquals(123, myClassMock.myMethod(1))
}
verify {
with(any<CallContext>()) {
myClassMock.myMethod(1)
}
}
}
}
以防萬一鏈接到要點
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.