假设有一个带有回调的接口:
interface SomeInterface {
fun doSomething(arg: String, callback: (Exception?, Long) -> Unit)
}
我将其扩展为这样的暂停函数:
suspend fun SomeInterface.doSomething(arg: String): Long = suspendCoroutine { cont ->
this.doSomething(arg) { err, result ->
if (err == null) {
cont.resume(result)
} else {
cont.resumeWithException(err)
}
}
}
我想在测试中模拟这个,但是失败了。 理想情况下,我想使用这样的东西:
@Test
fun checkService() {
runBlocking {
val myService = mock<SomeInterface>()
whenever(myService.doSomething(anyString())).thenReturn(1234L)
val result = myService.doSomething("")
assertEquals(result, 1234L)
}
}
上面的语法失败,并带有模仿异常,因为它期望回调的匹配器。
org.mockito.exceptions.misusing.InvalidUseOfMatchersException:
Invalid use of argument matchers!
2 matchers expected, 1 recorded:
如何模拟这样的暂停功能? 如果不可能使用类似的语法,我该如何使用所需的参数进行模拟调用,以使在我的代码中使用的suspend变体在测试期间返回所需的结果?
更新: 当它是扩展功能时,似乎是不可能的。根据{{3}}的评论,我认为这是因为扩展名只是静态函数,超出了Mockito的能力。
当suspend函数是成员函数时,它将按照我的原始语法正常工作。
这里是要点,其中包含一些演示代码: Marko Topolnik
答案 0 :(得分:1)
我建议您使用MockK进行测试,这对协程更友好。
要模拟协程,可以使用coEvery
和returns
,如下所示:
val interface = mockk<SomeInterface>()
coEvery { a.doSomething(any()) } returns Outcome.OK
答案 1 :(得分:1)
何时需要
在...上。确实返回..
并且方法被暂停,使用 mockito ,您可以使用此方法:
然后:
myObject.stub {
onBlocking { isFoo() }.doReturn(true)
}