Bas*_*tor 3 android unit-testing task mockito kotlin
因此,我正在编写一个方法来对与 Firebase 身份验证的交互进行单元测试 - 我已成功模拟了所需的所有其他内容,但我不确定如何模拟被测方法中的调用Tasks.await(someTask).someValue
因为Tasks.await()
是静态的,所以我不能真正嘲笑它。
我可以模拟任务本身,但不能模拟对await 方法的调用。有什么方法可以让我Tasks.await()
认为该任务是真实的,以便它正常运行吗?
我在这里可以做些什么吗?
我的协程有这个问题await
。我认为解决方案是模拟任务,因为协程await()
基本上包装了侦听器。我所做的是模拟最简单的路径await
。
/**
* Mocks the simplest behaviour of a task so .await() can return task or throw exception
* See more on [await] and inside of that on awaitImpl
*/
private fun mockTask(exception: Exception? = null): Task<Void> {
val task: Task<Void> = mockk(relaxed = true)
every { task.isComplete } returns true
every { task.exception } returns exception
every { task.isCanceled } returns false
val relaxedVoid: Void = mockk(relaxed = true)
every { task.result } returns relaxedVoid
return task
}
Run Code Online (Sandbox Code Playgroud)
如果你想知道的话,我正在使用Mockk 。
这是解释。内部await
简单地调用一个私有的awaitImpl
public suspend fun <T> Task<T>.await(): T = awaitImpl(null)
Run Code Online (Sandbox Code Playgroud)
然后awaitImpl
这样做
// fast path
if (isComplete) {
val e = exception
return if (e == null) {
if (isCanceled) {
throw CancellationException("Task $this was cancelled normally.")
} else {
@Suppress("UNCHECKED_CAST")
result as T
}
} else {
throw e
}
}
return suspendCancellableCoroutine { cont ->
addOnCompleteListener {...
Run Code Online (Sandbox Code Playgroud)
注释在源代码中。因此,该路径在添加用于测试的侦听器之前负责解析。我们只需要控制输出即可。所以模拟是说“输入完整的条件,然后我们控制异常是否为空。如果异常不为空,它将抛出它,否则,我们确定未取消,因此返回 Void”。
这让我想到:您可以将Void
, 更改为另一种类型。我正在为Task<Void>
.
然后使用它。
//for success
every { yourGoogleDependency.thatReturnsTask() } returns mockTask()
//for failure
every { yourGoogleDependency.thatReturnsTask() } returns mockTask(Exception())
Run Code Online (Sandbox Code Playgroud)