问题描述
我正在尝试测试以下RxKotlin/RxJava 2代码:
I'm trying to test the following RxKotlin/RxJava 2 code:
validate(data)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.flatMap { ... }
我试图按如下方式覆盖调度程序:
I'm attempting to override the schedulers as follows:
// Runs before each test suite
RxJavaPlugins.setInitIoSchedulerHandler { Schedulers.trampoline() }
RxAndroidPlugins.setInitMainThreadSchedulerHandler { Schedulers.trampoline() }
但是,运行测试时出现以下错误:
However, I get the following error when running the test:
java.lang.ExceptionInInitializerError
...
Caused by: java.lang.NullPointerException: Scheduler Callable result can't be null
at io.reactivex.internal.functions.ObjectHelper.requireNonNull(ObjectHelper.java:39)
at io.reactivex.plugins.RxJavaPlugins.applyRequireNonNull(RxJavaPlugins.java:1317)
at io.reactivex.plugins.RxJavaPlugins.initIoScheduler(RxJavaPlugins.java:306)
at io.reactivex.schedulers.Schedulers.<clinit>(Schedulers.java:84)
有人遇到过这个问题吗?
Has anyone experienced this problem?
在使用RxKotlin/RxJava 1并覆盖以下调度程序时,该测试工作正常:
The test worked fine when using RxKotlin/RxJava 1 and the following scheduler overrides:
RxAndroidPlugins.getInstance().registerSchedulersHook(object : RxAndroidSchedulersHook() {
override fun getMainThreadScheduler() = Schedulers.immediate()
})
RxJavaPlugins.getInstance().registerSchedulersHook(object : RxJavaSchedulersHook() {
override fun getIOScheduler() = Schedulers.immediate()
})
推荐答案
我建议您采用其他方法,并为调度程序添加抽象层.这个家伙有一个很好的文章关于它.
I suggest you take a different approach and add a layer of abstraction to your schedulers. This guy has a nice article about it.
在Kotlin中看起来像这样
It would look something like this in Kotlin
interface SchedulerProvider {
fun ui(): Scheduler
fun computation(): Scheduler
fun trampoline(): Scheduler
fun newThread(): Scheduler
fun io(): Scheduler
}
然后使用自己的SchedulerProvider实现覆盖它:
And then you override that with your own implementation of SchedulerProvider:
class AppSchedulerProvider : SchedulerProvider {
override fun ui(): Scheduler {
return AndroidSchedulers.mainThread()
}
override fun computation(): Scheduler {
return Schedulers.computation()
}
override fun trampoline(): Scheduler {
return Schedulers.trampoline()
}
override fun newThread(): Scheduler {
return Schedulers.newThread()
}
override fun io(): Scheduler {
return Schedulers.io()
}
}
还有一个用于测试班级的人:
And one for testing classes:
class TestSchedulerProvider : SchedulerProvider {
override fun ui(): Scheduler {
return Schedulers.trampoline()
}
override fun computation(): Scheduler {
return Schedulers.trampoline()
}
override fun trampoline(): Scheduler {
return Schedulers.trampoline()
}
override fun newThread(): Scheduler {
return Schedulers.trampoline()
}
override fun io(): Scheduler {
return Schedulers.trampoline()
}
}
您的代码在调用RxJava时将如下所示:
Your code would look like this where you call RxJava:
mCompositeDisposable.add(mDataManager.getQuote()
.subscribeOn(mSchedulerProvider.io())
.observeOn(mSchedulerProvider.ui())
.subscribe(Consumer<Quote> {
...
您将根据测试位置覆盖SchedulerProvider
的实现.这是一个示例项目供参考,我正在链接使用SchedulerProvider
的可测试版本的测试文件: https://github.com/Obaied/DingerQuotes/blob/master/app/src/test/java/com/obaied /dingerquotes/QuotePresenterTest.kt#L31
And you'll just override your implementation of SchedulerProvider
based on where you test it. Here's a sample project for reference, I am linking the test file that would use the testable-version of SchedulerProvider
: https://github.com/Obaied/DingerQuotes/blob/master/app/src/test/java/com/obaied/dingerquotes/QuotePresenterTest.kt#L31
这篇关于单元测试中的RxJava 2覆盖IO调度程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!