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
默认使用此调度程序。
我已将 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
默认使用此调度程序。