RxJava2 switchIfEmpty并验证执行

-2 android reactive-programming kotlin reactive rx-java2

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

LocalDatabase:

public Observable<PoiObject> getPoiObject() {

    return Observable.defer {
        PoiObject object = poiDao.getPoiObject();
        if(object == null) {
            return Observable.empty();
        }
        else {
            return Observable.just(object);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,我在其他地方有另一种方法,如下所示:

服务:

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

public Observable<PoiObject> getItFromWeb() {
    return restService.getObject()
}
Run Code Online (Sandbox Code Playgroud)

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

用例:

public Observable<SomeVM> getObject() {
    return service.getPoiObject()
        .switchIfEmpty(service.getItFromWeb())
}
Run Code Online (Sandbox Code Playgroud)

然后以下单元测试失败:

@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();
}
Run Code Online (Sandbox Code Playgroud)

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

aka*_*okd 8

打开一个大括号并不会神奇地使得超出它的代码/变量以惰性方式初始化.你写的是这个:

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

你已经getPoiObject()通过推迟执行来完成合理的工作,你也应该申请getObject():

public Observable getObject() {
    return service.getPoiObject()
             .switchIfEmpty(Observable.defer(() -> getItFromWeb()));
}
Run Code Online (Sandbox Code Playgroud)