Kotlin协同程序使用产品和mockito来模拟生产工作

时间:2017-12-02 00:47:31

标签: android unit-testing kotlin kotlinx.coroutines

我正在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上的一个方法,它通过使用来自ko​​tlin android coroutines库的launch(UI)协程的自定义Executor在ui线程中执行函数

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

然后repository.getVenues(..)函数也是一个使用produce(CommonPool) {}返回ProducerJob的协程

问题在于它接触到交互器函数中的成功回调似乎没有按照

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

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

我对协同程序有点新意,所以任何帮助都会受到赞赏。

1 个答案:

答案 0 :(得分:0)

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

val producerJob = produce { send(result.value) }