gpt4 book ai didi

android - 验证在 RxJava Subscriber 的 onNext 中调用了方法

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:12:30 25 4
gpt4 key购买 nike

我有以下使用 Retrofit 的方法服务接口(interface)从 API 获取一些数据,然后与 view 接口(interface)交互。

@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());
});
}

我想测试 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();


}

我显式传入 Scheduler Schedulers.immediate() 以确保在订阅线程上立即调用 onNext()

当我通过我的方法调试时,onNext() 没有被调用。我做错了什么或者我怎样才能最好地测试它?

编辑: This article让我想到了一些东西:

If you wish to change the thread on which the operation is performed you can call subscribeOn(). To get back to the main thread use observeOn(AndroidSchedulers.mainThread()). However, notice that whenever you force the operation onto a specific thread, it will always make the subscription asynchronous.

当我省略

        .subscribeOn(subscribeOn)
.observeOn(AndroidSchedulers.mainThread())

部分,测试按预期工作。我已将我的方法重新安排为在未传入调度程序时不调用 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());
});
}

看起来有点笨拙,但确实有效。

仍然欢迎任何想法:)

最佳答案

第一个示例很好,只需注入(inject) ui 调度程序并使用它。在您的测试中注入(inject)类似即时调度程序的东西,并在生产中注入(inject) Android ui 调度程序。一般来说,最好不要在类中硬编码依赖项,而是注入(inject)它们。这是依赖注入(inject)可能有所帮助的情况之一。

关于 subscribeOn 的注意事项:您不需要将它与 retrofit 一起使用,因为 retrofit 无论如何都会在默认线程上执行操作。将调度程序命名为“subscribeOn”和“observeOn”也没有多大意义,因为您可能希望使用相同的调度程序传递给 subscribeOn()observeOn() .鉴于它们所代表的内容,最好给它们起更有意义的名称,例如“backgroundScheduler”和“uiScheduler”

关于android - 验证在 RxJava Subscriber 的 onNext 中调用了方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33786948/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com