RxJava2 switchIfEmpty并验证执行

时间:2017-09-18 11:29:31

标签: android kotlin reactive-programming rx-java2 reactive

所以..想象一下,我有一个像这样的方法构造:

LocalDatabase:

public Observable<PoiObject> getPoiObject() {

    return Observable.defer {
        PoiObject object = poiDao.getPoiObject();
        if(object == null) {
            return Observable.empty();
        }
        else {
            return Observable.just(object);
        }
    }
}

现在,我在其他地方有另一种方法:

服务:

public Observable<PoiObject> getPoiObject() {
    return localDatabase.getPoiObject()
}

public Observable<PoiObject> getItFromWeb() {
    return restService.getObject()
}

如果我尝试将Service :: getPoiObject的调用链接到这样的Rx调用中:

USECASE:

public Observable<SomeVM> getObject() {
    return service.getPoiObject()
        .switchIfEmpty(service.getItFromWeb())
}

然后以下单元测试失败:

@Test
public void test_getObject() {
    Service service = mock()

    when(service.getPoiObject()).thenReturn(any());

    Observable<SomeVM> observable = usecase.getObject();
    verify(service).getPoiObject();
    verify(service, times(0)).getItFromWeb();
}

为什么getItFromWeb()在清楚地执行时,前一个调用不为空(从service.getPoiObject()调用返回对象)。是否还有其他策略可以在switchIfEmpty上进行测试?

1 个答案:

答案 0 :(得分:7)

打开一个大括号并没有神奇地使代码/变量超出它而以懒惰的方式初始化。你写的是这个:

public Observable<SomeVM> getObject() {
    Observable o1 = service.getPoiObject();
    Observable o2 = service.getItFromWeb();  // <-------------------
    Observable o3 = o1.switchIfEmpty(o2);
    return o3;
}

您已经通过推迟执行在getPoiObject()中完成了合理的工作,您也应该在getObject()中应用:

public Observable getObject() {
    return service.getPoiObject()
             .switchIfEmpty(Observable.defer(() -> getItFromWeb()));
}