asc*_*sco 5 android mockito rx-java
我有以下方法使用Retrofit服务接口从API获取一些数据,然后与view接口交互.
@Override
@VisibleForTesting
public void fetchPhotos(@Nullable PhotosService service, @Nullable Scheduler subscribeOn) {
view.showLoading();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(Constants.PLACEHOLDER_API_BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build();
if (service == null) service = retrofit.create(PhotosService.class);
if (subscribeOn == null) subscribeOn = Schedulers.newThread();
service.listPhotos()
.subscribeOn(subscribeOn)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(photoList -> {
Log.d(TAG, "got photos " + photoList.toString());
view.unshowLoading();
}, throwable -> {
Log.d(TAG, "error " + throwable.toString());
view.unshowLoading();
view.displayError(throwable.toString(), v -> fetchPhotos());
});
}
Run Code Online (Sandbox Code Playgroud)
我想测试view.unshowLoading()onNext中调用的那个.
这是我的测试:
@Test
public void viewUnshowsLoadingAfterFetchingPhotos() {
PhotosListView view = Mockito.mock(PhotosListView.class);
PhotosListPresenter presenter = new PhotosListPresenterImpl(view);
presenter.fetchPhotos(() -> Observable.create(new Observable.OnSubscribe<List<Photo>>() {
@Override
public void call(Subscriber<? super List<Photo>> subscriber) {
subscriber.onNext(new ArrayList<Photo>());
}
}), Schedulers.immediate());
Mockito.verify(view).unshowLoading();
}
Run Code Online (Sandbox Code Playgroud)
我明确传入Scheduler Schedulers.immediate()以确保onNext()在订阅线程上立即调用.
当我通过我的方法调试时,onNext()没有被调用.我做错了什么或者我怎么能最好地测试这个?
编辑: 这篇文章带给我的东西:
如果要更改执行操作的线程,可以调用subscribeOn().要返回主线程,请使用observeOn(AndroidSchedulers.mainThread()).但是,请注意, 每当您将操作强制到特定线程时,它总是会使订阅异步.
当我省略了
.subscribeOn(subscribeOn)
.observeOn(AndroidSchedulers.mainThread())
Run Code Online (Sandbox Code Playgroud)
部分,测试按预期工作.我已经重新安排我的方法没有调用observeOn()或subscribeOn()没有调度程序传入:
public void fetchPhotos(@Nullable PhotosService service, @Nullable Scheduler subscribeOn, @Nullable Scheduler observeOn) {
view.showLoading();
if (service == null) service = createService();
Observable<List<Photo>> observable = service.listPhotos();
if (subscribeOn != null) observable = observable.subscribeOn(subscribeOn);
if (observeOn != null) observable = observable.observeOn(observeOn);
observable.subscribe(photoList -> {
Log.d(TAG, "got photos " + photoList.toString());
view.unshowLoading();
}, throwable -> {
Log.d(TAG, "error " + throwable.toString());
view.unshowLoading();
view.displayError(throwable.toString(), v -> fetchPhotos());
});
}
Run Code Online (Sandbox Code Playgroud)
看起来有点笨拙,但有效.
任何想法仍然欢迎:)
第一个示例很好,只需注入 ui 调度程序并使用它即可。在测试中注入类似即时调度程序的东西,并在生产中注入 Android ui 调度程序。一般来说,最好不要在类中硬编码依赖项,而是注入它们。这是依赖注入可以提供帮助的情况之一。
注意subscribeOn:您不需要将其与改造一起使用,因为改造无论如何都会在默认线程上执行操作。此外,将调度程序命名为“subscribeOn”和“observeOn”没有多大意义,因为您可能希望使用相同的调度程序来传递到subscribeOn()和observeOn()。考虑到它们所代表的含义,最好给它们更有意义的名称,例如“backgroundScheduler”和“uiScheduler”
| 归档时间: |
|
| 查看次数: |
1219 次 |
| 最近记录: |