【发布时间】:2015-03-18 17:56:10
【问题描述】:
我想为内部使用 RxJava 的组件编写一种“黑盒测试”。
在内部,它使用Retrofit 返回Observable 进行httpcall,然后使用.flatmap() 对从改造中检索到的数据进行未来处理。我们的想法是给该组件一个Transformer,以便像这样在观察者上设置调度程序:
class DefaultTransformer <T> implements Transformer<T, T> {
public Observable<T> call(Observable<T> observable) {
return observable.subscribeOn(Schedulers.newThread()).observeOn(AndroidSchedulers.mainThread());
}
}
我的组件做这样的事情:
void execute(Transformer<T, T> scheduler){
Observable<List<Team>> observable = retrofitApi.getLeague(leagueId, seasonId)
.flatMap(new Func1<LeagueWrapper, Observable<List<Team>>>() {
@Override public Observable<List<Team>> call(LeagueWrapper wrapper) {
return Observable.just(wrapper.getLeague().getTeams());
}
});
observable.compose(transformer);
observable.subscribe(this);
}
在生产中,我将DefaultTransformer 作为参数传递,但对于单元测试,我想提交一个Transformer,它与单元测试在同一线程上运行,所以一切都应该同步运行(而不是异步)。
我试过了:
class UnitTestTransformer <T> implements Transformer<T, T> {
public Observable<T> call(Observable<T> observable) {
return observable.subscribeOn(Schedulers.test()).observeOn(AndroidSchedulers.test());
}
}
但它仍然在我的单元测试中异步运行。我也试过Scheduler.immediate()。 toBlocking() 似乎不是一个选项,因为它不再是 Observable。知道有什么问题吗?
【问题讨论】:
-
observable.compose(transformer);是问题所在。所有Observable实例都是不可变的,调用compose不会更改现有Observable,但会返回一个新实例(在您的代码中将被忽略)。observable.compose(transformer).subscribe(this)应该可以正常工作。 -
还有一件事。
retrofit返回的所有Observable已经指定了Scheduler,因为retrofit在内部调用subscribeOn。再调用一次subscribeOn实际上并不会改变执行网络调用的最终调度程序。 -
如果你想测试你的代码,你应该使用
toBlocking操作符(在大多数RxJava单元测试中使用得非常多) -
嗨,感谢
compose()的提示!所以没有机会更新改造的Scheduler?toBlock()对我不起作用,因为我无法更改组件的execute()方法,或者您是否看到了解决方法? execute 方法将在内部调用(在其他非 RxJava 调用中)。我唯一能做的就是将Scheduler设置为Component.setScheduler(Transformer t),这将作为参数传递给Component.execute()
标签: rx-java rx-android