1

我正在我的 Android 应用程序中测试 Kotlin 协程,并且我正在尝试进行以下单元测试

@Test fun `When getVenues success calls explore venues net controller and forwards result to listener`() = 
    runBlocking {
      val near = "Barcelona"
      val result = buildMockVenues()
      val producerJob = produce<List<VenueModel>>(coroutineContext) { result.value }
      whenever(venuesRepository.getVenues(eq(near))) doReturn producerJob // produce corooutine called inside interactor.getVenues(..)

      interactor.getVenues(near, success, error) // call to real method

      verify(venuesRepository).getVenues(eq(near))
      verify(success).invoke(argThat {
        value == result.value
      })
}

交互器方法如下

fun getVenues(near: String, success: Callback<GetVenuesResult>,
  error: Callback<GetVenuesResult>) =
postExecute {
  repository.getVenues(near).consumeEach { venues ->
    if (venues.isEmpty()) {
      error(GetVenuesResult(venues, Throwable("No venues where found")))
    } else {
      success(GetVenuesResult(venues))
    }
  }
}

postExecute{..}是一个BaseInteractor在 ui 线程中通过自定义 Executor 执行函数的方法,该 Executor 使用launch(UI)来自 kotlin android coroutines library的 coroutine

fun <T> postExecute(uiFun: suspend () -> T) =
  executor.ui(uiFun)

然后该repository.getVenues(..)函数也是一个协程,它使用返回 ProducerJobproduce(CommonPool) {}

问题是它似乎没有按照交互函数中的成功回调执行

verify(success).invoke(argThat {
  value == result.value
})

但是,我在调试时确实看到交互器函数中的执行到达了if (venues.isEmpty())内部的行,consumeEach但随后从那里退出并继续测试,显然在验证成功回调时失败。

我对协程有点新,所以任何帮助都将不胜感激。

4

1 回答 1

0

我想出了这个。我看到问题出在这个生产协程上,而不是其他也在使用协程并且工作得很好的测试。我注意到我实际上错过了模拟 ProducingJob 上的发送,以便让它实际产生一个值,在这种情况下是模拟列表。我刚刚补充说,将制作工作的模拟更改为

val producerJob = produce { send(result.value) }
于 2017-12-02T15:13:17.737 回答