单元测试协程runBlockingTest:此作业尚未完成 [英] Unit testing coroutines runBlockingTest: This job has not completed yet

查看:37
本文介绍了单元测试协程runBlockingTest:此作业尚未完成的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请在下面找到一个使用协程替换回调的函数:

override suspend fun signUp(authentication: Authentication): AuthenticationError {
    return suspendCancellableCoroutine {
        auth.createUserWithEmailAndPassword(authentication.email, authentication.password)
            .addOnCompleteListener(activityLifeCycleService.getActivity()) { task ->
                if (task.isSuccessful) {
                    it.resume(AuthenticationError.SignUpSuccess)
                } else {
                    Log.w(this.javaClass.name, "createUserWithEmail:failure", task.exception)
                    it.resume(AuthenticationError.SignUpFail)
                }
            }
    }
}

现在我想对该函数进行单元测试。我正在使用Mockk:

  @Test
  fun `signup() must be delegated to createUserWithEmailAndPassword()`() = runBlockingTest {

      val listener = slot<OnCompleteListener<AuthResult>>()
      val authentication = mockk<Authentication> {
        every { email } returns "email"
        every { password } returns "pswd"
      }
      val task = mockk<Task<AuthResult>> {
        every { isSuccessful } returns true
      }

      every { auth.createUserWithEmailAndPassword("email", "pswd") } returns
          mockk {
            every { addOnCompleteListener(activity, capture(listener)) } returns mockk()
          }

    service.signUp(authentication)

      listener.captured.onComplete(task)
    }

遗憾的是,由于以下异常,此测试失败:java.lang.IllegalStateException: This job has not completed yet

我尝试将runBlockingTest替换为runBlocking,但测试似乎在无限循环中等待。

有人能帮我搬一下这个UT吗?

提前谢谢

推荐答案

thisPOST所示:

此异常通常表示测试中的某些协程被安排在测试范围(更确切地说是测试调度程序)之外。

不执行此操作:

private val networkContext: CoroutineContext = TestCoroutineDispatcher()

private val sut = Foo(
  networkContext,
  someInteractor
)

fun `some test`() = runBlockingTest() {
  // given
  ...

  // when
  sut.foo()

  // then
  ...
}

创建通过测试调度程序的测试范围:

private val testDispatcher = TestCoroutineDispatcher()
private val testScope = TestCoroutineScope(testDispatcher)
private val networkContext: CoroutineContext = testDispatcher

private val sut = Foo(
  networkContext,
  someInteractor
)

然后在测试中执行testScope.runBlockingTest

fun `some test`() = testScope.runBlockingTest {
  ...
}

另见Craig Russell"Unit Testing Coroutine Suspend Functions using TestCoroutineDispatcher"

这篇关于单元测试协程runBlockingTest:此作业尚未完成的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆