android - 使用 Completable.timer 对 RxJava 进行单元测试
问题描述
Android Studio 3.5.2
RxJava2
Kotlin 1.3.50
我有下面的类,它就像一个计时器。
class DelayTimerImp(private val scheduler: IScheduler)
: DelayTimer {
override fun createTimeout(delay: Long, timeUnites: TimeUnit): Completable {
return Completable.timer(delay, TimeUnit.SECONDS, scheduler.main())
}
}
我正在以这样的方法使用它:
private fun startTimeoutRequest(delay: Long) {
compositeSubscription.add(delayTimer.createTimeout(delay, TimeUnit.SECONDS)
.subscribeOn(schedulers.io())
.subscribe(::timeoutHasExceeded, ::timeoutError))
}
在我的测试类中,它使用TestScheduler
来返回io
线程。我在嘲笑delayTimer。即使我从未涉足其中thenReturn(Completable.complete())
的方法。timeOutHasExceeded
我在想如果Completable
已经完成了进入那个方法。
@Test
fun `should reload and show loading state`() {
// Arrange
whenever(delayTimer.createTimeout(10, TimeUnit.SECONDS))
.thenReturn(Completable.complete())
// Act
vipInformationPresenterImp.tryAgainTapped()
// Assert methods in the timeOutHasExceeded
}
此外,如果我通过将延迟更改为1
:
whenever(delayTimer.createTimeout(1, TimeUnit.SECONDS))
.thenReturn(Completable.complete())
我将crash
在以下行中得到一个:
.subscribeOn(schedulers.io())
对此进行单元测试的最佳方法是什么?
提前谢谢了
解决方案
根据本教程,您应该使用 TestScheduler 覆盖这些:
class TestSchedulerProvider(private val scheduler: TestScheduler) : BaseSchedulerProvider {
override fun computation() = scheduler
override fun ui() = scheduler
override fun io() = scheduler
}
然后稍后本教程使用 TestScheduler 如下:
@Test
fun delayTestExample() {
//given
val presenter = DemoPresenter(testSchedulerProvider, view, service)
given(service.getSomeRemoteData()).willReturn(Single.just(5))
val delayInMillis = 1000L
//when
presenter.getSomeDataWithDelay(delayInMillis)
//then
then(view).should(never()).showData(anyInt())
// HERE:
testScheduler.advanceTimeBy(delayInMillis, TimeUnit.MILLISECONDS)
then(view).should().showData(5)
}
的使用在代码中的advanceTimeBy
注释下进行了描述。//HERE:
是否可以使用相同的方法,而不是您的:
whenever(delayTimer.createTimeout(1, TimeUnit.SECONDS))
.thenReturn(Completable.complete())
你会打电话给例如:
testScheduler.advanceTimeBy(1500, TimeUnit.MILLISECONDS)
在您创建超时和我选择的 1500 之后的行中,以便在advanceTimeBy 继续之前真正在计时器中打勾 1 秒。不过,它应该与每个 > 1000 的值都很好,我只是想确定一下;)
推荐阅读
- laravel - 使用 Laravel 批量插入,无需任何循环
- android - android中的字体系列使用
- reactjs - React Native:如何根据 Scroll 或 Y contentOffset 更改状态栏样式
- c++ - 使用 -fPIC /usr/bin/ld 重新编译:最终链接失败:输出错误时出现不可表示的部分
- ruby-on-rails - 使用 sqlite3 在 ruby 中的脚手架有问题
- c++ - 将分数转换为十进制数并对其进行排序
- powershell - 如何在 powershell 文件中包含带有变量的 CURL URL?
- reactjs - Redux useDispatch 返回一个 Array React Hooks?
- sql - 错误日期格式图片在转换整个输入字符串之前结束
- variables - 明确指定类型与在 Kotlin 中不明确指定有什么区别?