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);
}
答案 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我对缓存的建议。