如何使用Mockito验证RxJava2 Observable上没有交互

时间:2017-05-19 13:49:57

标签: android testing mockito rx-java2

Observable是最终类,因此我们无法为其创建模拟来验证或捕获对其执行的任何交互。

和Observable的test(),TestSubscriber也没有提供任何这样的交互断言技术

我创建了一个通用方法,用于在从网络

加载之前检查缓存数据
/**
 * General parametrized method for loading data from service while checking connection
 * and respecting reload state
 */
private <T> Observable<T> getData(Observable<T> dataSource, String key, boolean reload) {
    T cachedData = (T) cacheModel.getValue(key);

    // Do not use cache if reloading
    if(!reload && cachedData != null)
        return Observable.just(cachedData);

    if(!utilModel.isConnected()) {
        return Observable.error(new Throwable(Constants.NO_NETWORK));
    }

    return dataSource
        .doOnNext(data -> cacheModel.saveObject(key, data))
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread());
}

使用如下:

@Override
public Observable<User> getOrganiser(boolean reload) {
    return getData(eventService.getUser(authorization), ORGANIZER, reload);
}

之前,我甚至没有调用eventService.getUser(...)来获取observable,所以我可以测试它是否从未被调用过,但是现在,因为我必须将它传递给模板方法,所以我需要调用它但要验证缓存是否存在,它永远不会与之交互。

这是我之前的测试,显然现在失败了

@Test
public void shouldLoadOrganizerFromCache() {
    // Clear cache
    objectCache.clear();

    User user = new User();
    objectCache.saveObject(RetrofitEventRepository.ORGANIZER, user);

    // No force reload ensures use of cache
    Observable<User> userObservable = retrofitEventModel.getOrganiser(false);

    userObservable.test().assertNoErrors();
    userObservable.test().assertValue(user);

    verify(eventService, never()).getUser(auth);
}

1 个答案:

答案 0 :(得分:1)

假设您想要测试的Observable是这样的:

Observable<User> userObservable = getData(eventService.getUser(authorization));

虽然您无法直接使用test()方法或订阅TestObserver,但您将输入Observable传递给其他实体。您可以使用Observable副作用方法验证几乎与Observable的任何互动 例如,在你的情况下,你可以使用doOnSubscribe并在调用时引发一个标志(表示调用服务方法,而不应该调用缓存):

final boolean[] serviceCalled = new boolean[1];
Observable<User> userServiceObservable = eventService.getUser(authorization)
            .doOnSubscribe(disposable -> serviceCalled[0] = true);

Observable<User> userObservable = getData(userServiceObservable, ORGANIZER, reload);
userObservable.test()
        .assertNoErrors()
        .assertValue(user)
        .awaitTerminalEvent();
Assert.assertEquals(false, serviceCalled[0]);
顺便说一下,你的缓存方法可能无法正常运行,因为你在获取Observable时测试缓存而不是在订阅时,因此缓存状态在订阅时可能会有所不同。同时多次调用可能同时发生,导致多次调用服务器并更新缓存,您可以使用Observable.defer()查看here我对缓存的建议。