Let's say there's an interface with a callback:

interface SomeInterface {
    fun doSomething(arg: String, callback: (Exception?, Long) -> Unit)
}

which I extend into a suspend function like this:

suspend fun SomeInterface.doSomething(arg: String): Long = suspendCoroutine { cont ->
    this.doSomething(arg) { err, result ->
        if (err == null) {
            cont.resume(result)
        } else {
            cont.resumeWithException(err)
        }
    }
}

I'd like to mock this in tests, but am failing. Ideally I'd like to use something like this:

@Test
fun checkService() {
    runBlocking {
        val myService = mock<SomeInterface>()
        whenever(myService.doSomething(anyString())).thenReturn(1234L)
        val result = myService.doSomething("")
        assertEquals(result, 1234L)
    }
}

上述语法因mockito异常而失败,因为它期待回调使用匹配器.

org.mockito.exceptions.misusing.InvalidUseOfMatchersException: 
Invalid use of argument matchers!
2 matchers expected, 1 recorded:

How can I mock a suspend function like that? If a similar syntax is not possible how can I have the mock call back with the desired arguments such that the suspend variant that is used throughout my code returns the desired result during tests?

Update: It seems it's not possible when it's an extension function. Based on Marko Topolnik's comment, I gather it's because an extension is simply a static function which is out of mockito's capability.

When the suspend function is a member function, then it works as expected, with my original syntax.

以下是一些演示代码的要点:

推荐答案

I suggest using MockK for your tests, which is more coroutine-friendly.

To mock a coroutine, you can use coEvery and returns like below:

val interf = mockk<SomeInterface>()
coEvery { a.doSomething(any()) } returns Outcome.OK

Kotlin相关问答推荐

直接从SON解析NonEmptyList

解决Microronaut中多个可能的Bean候选者冲突

如何进行基于lambda/谓词的两个列表的交集?

在 Kotlin 中将 Array 转换为 IntArray 时丢失值

Java/Kotlin中类似Rust般的注释编译?

如何从 Period.between() 返回的字符串中提取信息? (Kotlin )

如何获取@JsonProperty 名称列表?

Kotlin 使用委托进行隐式覆盖

如果不为空,则为 builder 设置一个值 - Kotlin

我们应该在 Effect 和 Either 之间 Select 哪个作为我们业务服务的返回类型?

关于 Kotlin 函数类型转换的问题

T except one class

判断 AAR 元数据值时发现的一个或多个问题:

如何使用 Kotlin Coroutines 使 setOnClickListener debounce 1 秒?

将 Android Studio 升级到 3.1.0 后的 Android Support 插件错误

Android Studio 将 Java 转换为 Kotlin 错误无法推断此参数的类型

如何将map函数应用于Kotlin中的数组并更改其值?

(kotlin的Moshi)@Json vs@field:Json

类型不匹配推断类型为单位,但应为空

WebFlux 功能:如何检测空 Flux 并返回 404?