【发布时间】:2016-12-02 16:15:02
【问题描述】:
在我的应用程序中,我使用 Repository 和 RxJava 访问我的业务对象。从我的 Presenter 层,我可以要求 Repository 获取我的 ObjectA 或获取我的 ObjectB,Respository 将分别返回一个 Observable 或 Observable。
有时我需要同时获取 ObjectA 和 ObjectB。我想知道使用 RxJava 获取这两个对象的选项是什么,它还允许对我的 Presenter 层进行单元测试。
我最初实现它的方式是使用 flatMap() 运算符。所以我会做这样的事情:
//In Presenter layer
Observable<ObjectA> obsA = repository.getObjectA();
Observable<ObjectB> obsB = repository.getObjectB();
Observable<ObjectB> obsResult = obsA.flatMap(new Func1<ObjectA, Observable<ObjectB>>() {
@Override
public Observable<ObjectB> call(ObjectA a) {
mObjectA = a;
return obsB;
}
});
当我订阅 obsResult 时,obsA 运行,我可以在 flatMap() 运算符中访问它的结果。我得到了它的结果的句柄,并将它作为一个字段存储在我的 Presenter 中。然后 obsB 运行,我在我的订阅者中得到它的结果。这工作得很好,但我不禁认为我做得不对。一个问题是,虽然我的 Repository 类中可能有 100% 的测试覆盖率,但现在我正在处理来自 Repository 类的可观察对象,我很难弄清楚如何测试 obsResult 或验证我在 flatMap() 中写的代码是正确的。
我是否应该向我的存储库层添加方法,例如 getObjectAandObjectB 并返回一个 Observable 并在存储库层中完成所有工作?这将允许我在 Repository 层测试中测试生成的 Observable,而不是尝试从两个单独的 Observable 创建一个新的 Observable 并弄清楚如何在我的 Presenter 层中对其进行测试。
我看到的另一件事是使用 zip() 运算符。这看起来像这样:
Observable<ObjectA> obsA = repository.getObjectA();
Observable<ObjectB> obsB = repository.getObjectB();
Observable<CombinedObjectAandObjectB> resultObs = obsA.zipWith(obsB, new Func2<ObjectA, ObjectB, CombinedObjectAandObjectB>() {
@Override
public Object call(ObjectA a, ObjectB b) {
return new CombinedObjectAandObjectB(a,b);
}
});
现在,当我订阅我的 resultObs 时,我得到了一个包含 ObjectA 和 Object B 的复合对象。这非常巧妙,但仍然需要我在 Func2 中编写需要测试的代码。
有哪些方法可以实现我的目标,即组合对业务对象的调用,同时还允许结果 Observable 的可测试性?
【问题讨论】:
标签: android unit-testing rx-java