我想为组件编写一种“blackbox测试”,内部使用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
。知道什么可能是错的吗?
答案 0 :(得分:2)
如果无法更改调用execute()
的模式,则可能需要尝试使用RxJava插件机制。
https://github.com/ReactiveX/RxJava/wiki/Plugins
您可以提供:
RxJavaSchedulersHook
覆盖测试执行期间提供的调度程序并让它们同步执行RxJavaObservableExecutionHook
挂钩到Observable执行管道并使用某种同步方法(如CountdownLatch)等待Observable订阅完成后再继续答案 1 :(得分:0)
我遇到了类似的问题并使用TestObserver类(http://reactivex.io/RxJava/javadoc/rx/observers/TestObserver.html)
解决了这个问题它有以下三种方法可以访问收到的事件:
getOnCompletedEvents()
getOnErrorEvents()
getOnNextEvents()
我希望如果您能以某种方式注入您的订阅者,这也可以帮助您。 以下是我测试它的示例:
TestObserver<MyModel> testObserver = new TestObserver<>();
myObservableSupplyingMethod().subscribe(testObserver);
assertThat(testObserver.getOnErrorEvents().size()).isEqualTo(0);
assertThat(testObserver.getOnNextEvents().get(0)).isNotNull();
...