【问题标题】:RxJava test `repeat` on observable create endless loop on tests可观察的 RxJava 测试“重复”在测试中创建无限循环
【发布时间】:2020-03-03 18:34:59
【问题描述】:

我已设置我的ViewModel 以这种方式无休止地重复 API 调用:

useCase.fireAPICall(params)
   .subscribeOn(Schedulers.io())
   .observeOn(AndroidSchedulers.mainThread())
   .repeat()
   .delay(1, TimeUnit.SECONDS)
   .subscribe(::onSuccess, ::onFailed)

在我的单元测试中,我试图模拟 API 调用并检查 ViewModel 内的 LiveData(在 ::OnSuccess 方法中更新)是否相应更新。

工作单元测试,测试失败:

val error = Throwable("")
// Arrange
Mockito.`when`(repo.apiCall(params))
   .thenReturn(Single.error(error))
// Act
viewModel.init()
// Verify
Mockito.verify(postDetailsViewStateObserver)
   .onChanged(Error(error))

** Non-working:** f 相反,我尝试模拟来自该 API 调用的有效响应:

// Arrange
Mockito.doReturn(Single.just(Success(result, list)))
   .`when`(repo).apiCall(params)

然后ViewModelrepeat() 会生成一个无限循环,它会阻止我的单元测试而永远不会完成它。

问题:我们如何通过仅检查该 observable 上发出的第一件事来测试 repeat() 情况?

【问题讨论】:

  • 你必须在测试中缩短序列。

标签: android unit-testing kotlin mockito rx-java


【解决方案1】:

您需要为delay 提供调度程序以利用测试时间,例如:

val testScheduler = TestScheduler()
RxJavaPlugins.setComputationSchedulerHandler { testScheduler }

在那次电话testScheduler.advanceTimeBy(1, TimeUnit.SECONDS) 之后,您将前进一秒钟。为了使它起作用,您可能还应该更改顺序,delay 应该在repeat 之前。

您需要setComputationSchedulerHandler,因为delay 默认使用此调度程序。

【讨论】:

  • repeat 实际上是在delay 之后。那是一个糟糕的复制粘贴。感谢您的回复,它成功了!
猜你喜欢
  • 1970-01-01
  • 2018-05-24
  • 1970-01-01
  • 2018-01-13
  • 2023-01-22
  • 1970-01-01
  • 2018-04-28
  • 2010-12-17
  • 2023-02-01
相关资源
最近更新 更多