unit-testing - rxjava testScheduler 竞争条件
问题描述
我偶然发现了一个奇怪的 testScheduler 行为,我无法理解。下面的代码被大大简化了,但它源于现实生活中的问题。
考虑这个测试:
@Test
fun testSchedulerFun(){
val testScheduler = TestScheduler()
val stringsProcessor = PublishProcessor.create<String>()
val completable = Completable.complete()
completable
.doOnComplete { stringsProcessor.onNext("onComplete") }
.subscribeOn(testScheduler)
.subscribe()
val testSubscriber = stringsProcessor
.subscribeOn(testScheduler) //this line of code messes the test
.test()
testScheduler.triggerActions()
testSubscriber
.assertValues("onComplete")
}
**当我订阅 test stringsProcessor
ontestScheduler
时,测试失败。当我删除该行时,它成功了。**
我看到的事件流程是:
- 触发动作
- 正在订阅 completable 和 stringsProcessor 并将它们的事件传播到下游。
- 显然,在 testSubscriber 完成后
stringsProcessor.onNext("onComplete")
评估。
我想知道为什么
解决方案
测试失败的原因是因为stringProcessor
在您调用它时没有订阅者onNext
。该订阅者仅在您添加了“这条线搞砸了”之后才出现subscribeOn
。
不涉及竞争条件,因为一切都以确定的顺序在同一个线程上运行:
- 当代码执行
completable ... subscribe()
部分时testScheduler
,将执行 doOnComplete 调用的任务排队。 - 当代码执行该
test
部分时,另一个任务会排队testScheduler
,它将观察处理器。 - triggerActions 执行任务 1,它不向任何订阅者发出值,然后执行任务 2,现在准备观察处理器,但什么也没有。
推荐阅读
- io - 捕获模块输出
- postgresql - PostgreSQL SELECT COUNT 返回一堆 1
- java - XPATH - getAttribute() 和 writer.append() 到 CSV 文件(Selenium/Selenide)
- ruby-on-rails - React w/Rails API,突然的代理错误?!ECONNRESET 代理错误:无法将请求从 localhost:3000 代理到 http://localhost:3001/
- r - 在R中将字符串作为参数传递
- dart - 如何在颤动中删除屏幕上的空文本
- mesos - 创建 minidcos 集群时出现代码 VBOX_E_OBJECT_NOT_FOUND (0x80bb0001) 错误
- php - 如何从 Laravel 控制器发送换行符以在刀片页面消息中显示多行
- python-3.x - 在 Python 3 中使用请求进行的 API 调用返回 HTML 而不是 JSON
- python - pyinstaller,找不到文件回溯错误