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(...)
来获取可观察量,因此我可以测试它是否从未被调用,但现在,由于我必须将其传递给模板方法,我需要调用它但验证缓存是否存在,它永远不会与之交互。
这是我之前的测试,现在显然失败了
@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);
}
假设您要测试的可观察量是这样的:
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()
进行缓存的建议。