如何使用回调函数对挂起函数进行单元测试

3

我有以下代码:

suspend fun initialize(sdk: Sdk) =
    suspendCoroutine<Unit> { continuation ->
        try {
            sdk.initialize(
                callback = { continuation.resume(Unit) },
                onFailure = { error -> continuation.resumeWithException(SdkException(error.message)) })
        } catch (exception: Exception) {
            continuation.resumeWithException(
                SdkException("Crash inside SDK", exception)
            )
        }
    }

SDK是一个第三方库。我使用来挂起协程,并在SDK完成初始化后恢复。 一切工作正常,但当我尝试编写如下的单元测试时,会收到以下错误信息:。我使用mockito-kotlin编写以下测试:

    @Test
    fun `should initialize sdk correctly`() = runBlockingTest {
        val sdk = mock<Sdk>()

        initializeSdk(sdk)

        verify(sdk).initialize(any(), any())
    }

我想要做的基本上就是测试resumeresumeWithException

1个回答

1

就我个人而言,我不是模拟测试的粉丝。如果 Sdk 是一个接口,你可以提供自己的测试实现来执行测试(成功和错误结果)。你可以完全控制回调函数被调用的时间/是否被调用等。

如果 Sdk 是一个无法控制的类,你可以创建一个接口来抽象 Sdk 类,并使你的 initialize 方法使用你自己的接口。然而,我必须承认这并不理想。

如果你坚持使用模拟测试,通常模拟库有一种方法让你使用调用参数来模拟方法调用的响应。使用 Mockito 库,应该是这样的:

val sdk = mock<Sdk> {
    on { initialize(any(), any()) } doAnswer { invocation ->
        @Suppress("UNCHECKED_CAST")
        val successCallback = invocation.arguments[0] as (() -> Unit) // use callback's function type here
        successCallback.invoke()
    }
}

(虽然我不是Mockito的专家,所以可能有更简洁或类型安全的方法:D)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接