RxJava在与单元测试相同的线程上订阅和观察

时间:2015-03-18 17:56:10

标签: rx-java rx-android

我想为组件编写一种“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。知道什么可能是错的吗?

2 个答案:

答案 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();
...