RxJava 在 observable 上测试 `repeat` 在测试上创建无限循环

RxJava test `repeat` on observable create endless loop on tests

我已将 ViewModel 设置为以这种方式无限重复 API 调用:

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

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

Working 测试失败的单元测试:

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

** 非工作:** f 相反,我尝试模拟来自 API 调用的有效响应:

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

然后 ViewModel repeat() 生成一个无限循环,它阻止了我的单元测试而没有完成它。

问题: 我们如何通过仅检查那个可观察对象发出的第一件事来测试 repeat() 情况?

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

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

然后调用 testScheduler.advanceTimeBy(1, TimeUnit.SECONDS) 这样您将向前移动一秒钟。为了让它工作,您可能还应该更改顺序,delay 应该在 repeat 之前。

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