Android 测试rxjava间隔
我在ViewModel中有一个重复的可观察到的,如下所示:Android 测试rxjava间隔,android,unit-testing,rx-java2,rx-android,Android,Unit Testing,Rx Java2,Rx Android,我在ViewModel中有一个重复的可观察到的,如下所示: class MainViewModel @Inject constructor(private val ratesUseCase: RatesUseCase) : ViewModel() { private var disposable: Disposable? = null private val resultLiveData = MutableLiveData<Resource<Map<Strin
class MainViewModel @Inject constructor(private val ratesUseCase: RatesUseCase) : ViewModel() {
private var disposable: Disposable? = null
private val resultLiveData = MutableLiveData<Resource<Map<String, Double>>>()
fun result() = resultLiveData
fun getRates(base: String) {
disposable = Observable
.interval(1, TimeUnit.SECONDS)
.flatMap { ratesUseCase.execute(base) }
.doOnSubscribe { publishResult(Resource.loading(mapOf())) }
.subscribe(
{
publishResult(Resource.success(values))
},
{
publishResult(Resource.error(it.localizedMessage, mapOf()))
}
)
}
}
如果不将
调度程序
传递给可观察的.interval
,就会发生这种情况
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.COMPUTATION)
public static Observable<Long> interval(long period, TimeUnit unit) {
return interval(period, period, unit, Schedulers.computation());
}
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.COMPUTATION)
公共静态可观测间隔(长周期,时间单位){
返回间隔(周期、周期、单位、Schedulers.computation());
}
它将使用调度程序.computation()
作为默认调度程序
测试线程将刚刚完成,而interval
将无法发出任何消息
您必须使用TestScheduler
正确测试间隔。
请看这里:
您可以在ViewModel中覆盖计算调度程序或将TestScheduler
传递到Observable.interval
。
然后您可以
TestScheduler.advanceTimeBy
并控制您的间隔发射。我确实修复了这里的测试,我就是这样做的。
这里可以观察到两种情况:
1-可通过1
秒的interval()
观察到
2-可观察到的速率secase.execute(base)
。
如下所示,在MainViewModel
Observable
.interval(1, TimeUnit.SECONDS)
.flatMap { ratesUseCase.execute(base) }
.doOnSubscribe { publishResult(Resource.loading(mapOf())) }
.subscribe(
{
publishResult(Resource.success(values))
},
{
publishResult(Resource.error(it.localizedMessage, mapOf()))
}
)
在MainViewModel
Observable
.interval(1, TimeUnit.SECONDS)
.flatMap { ratesUseCase.execute(base) }
.doOnSubscribe { publishResult(Resource.loading(mapOf())) }
.subscribe(
{
publishResult(Resource.success(values))
},
{
publishResult(Resource.error(it.localizedMessage, mapOf()))
}
)
1-为ratesecase.execute(base)
2-使用RxJavaPlugins.setComputationSchedulerHandler
更改默认调度程序,如下所示
@Before
fun setUp() {
val testScheduler = TestScheduler()
RxJavaPlugins.setComputationSchedulerHandler { testScheduler }
ratesUseCase = RatesUseCase(appSchedulers, currencyRepository)
viewModel = MainViewModel(ratesUseCase)
}
3-使用testScheduler.advanceTimeTo
测试间隔。请不要忘记,这里的订单很重要,如下所示:
class MainViewModel @Inject constructor(private val ratesUseCase: RatesUseCase) : ViewModel() {
private var disposable: Disposable? = null
private val resultLiveData = MutableLiveData<Resource<Map<String, Double>>>()
fun result() = resultLiveData
fun getRates(base: String) {
disposable = Observable
.interval(1, TimeUnit.SECONDS)
.flatMap { ratesUseCase.execute(base) }
.doOnSubscribe { publishResult(Resource.loading(mapOf())) }
.subscribe(
{
publishResult(Resource.success(values))
},
{
publishResult(Resource.error(it.localizedMessage, mapOf()))
}
)
}
}
3.a:模拟存储库
3.b:观察ViewModel LiveData
3.c:提前时间间隔
3.d:验证结果
val base = "BASE"
whenever(currencyRepository.getRates(base))
.thenReturn(Observable.just(map))
viewModel.result().observeForever(observer)
viewModel.getRates(base)
testScheduler.advanceTimeTo(1, TimeUnit.SECONDS)
verify(observer).onChanged(
Resource.success(map)
)
可以找到完整的项目和测试用例您是否覆盖了运行间隔的计划程序?是!像这样subscribeOn(Schedulers.trampoline()).observeOn(Schedulers.trampoline())
默认情况下,interval在计算线程上运行。您应该能够使用RxJavaPlugins API为测试设置新的调度程序。使用setInitComputationSchedulerHandler将在计算调度器上运行的所有内容路由到trampoline()调度器。现在我已经将它们注入。Interval现在在Schedulers.trampoline()
Observable.Interval(1,TimeUnit.SECONDS)、compose(appSchedulers.ObservateTransformer())
上运行,但仍然给出相同的结果,我明白了。您是否尝试调试onNext和onComplete以查看它们是否实际按顺序运行?这很奇怪。另外,您还运行InstantTaskExecutorRule,对吗?