Compruebe que el método se llama en onNext del suscriptor de RxJava
Tengo el siguiente método que utiliza una interfaz de servicio de Retrofit para buscar algunos datos de una API, a continuación, interactúa con una interfaz de 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()); }); }
Quiero probar que view.unshowLoading()
se llama en onNext.
- Uso de Mockito con Retrofit 2.0
- ¿Qué es RxJava equivalente de orElse
- ¿Cómo puedo hacer que este zip rxjava funcione en paralelo?
- ¿Cómo ejecutaría esta sentencia usando RxJava?
- Observer.onError disparando de manera incoherente
Aquí está mi prueba:
@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(); }
Paso explícitamente en el Scheduler
Schedulers.immediate()
para asegurarse de que onNext()
se llama al instante en el hilo de suscripción.
Cuando onNext()
través de mi método sin embargo, onNext()
no se llama. ¿Qué estoy haciendo mal o cómo podría probar mejor esto?
EDIT: Este artículo me trajo a algo:
Si desea cambiar el hilo en el que se realiza la operación puede llamar a subscribeOn (). Para volver al tema principal use observeOn (AndroidSchedulers.mainThread ()). Sin embargo, tenga en cuenta que siempre que fuerce la operación en un hilo específico, siempre hará que la suscripción asynchronous .
Cuando omito el
.subscribeOn(subscribeOn) .observeOn(AndroidSchedulers.mainThread())
Parte, la prueba funciona como se esperaba. He reorganizado mi método para no llamar en observeOn()
o subscribeOn()
cuando no se pasan los planificadores:
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()); }); }
Parece un poco torpe, pero funciona.
Cualquier idea todavía bienvenida 🙂
- Retrofit no desencadena onError cuando se utiliza ErrorHandler personalizado
- Android RxJava que se une a las listas
- Cómo emitir elementos de una lista con retraso en RxJava?
- ¿Cómo puedo manejar excepciones en map () en un Observable en RxJava
- RxJava como bus de eventos en proyecto Android - eliminar evento del bus
- Observable.just () que devuelve Unidad en Kotlin
- Retrofit / Rxjava y servicios basados en sesiones
- Suscribir 2 diferentes Observable y onNext ambos?
La primera muestra está bien, sólo tiene que inyectar el planificador de ui y usarlo. En su prueba de inyectar algo como un planificador inmediato, y en la producción de inyectar el programador Android ui. En general es mejor no codificar las dependencias en sus clases, sino más bien inyectarlas. Este es uno de los casos en los que la inyección de dependencia podría haber ayudado.
Una nota sobre subscribeOn
: no es necesario utilizarlo con retrofit ya que la retrofit realizará la operación en un hilo predeterminado de todos modos. También nombrar planificadores "subscribeOn" y "observerOn" no tiene mucho sentido, ya que es posible que desee utilizar el mismo programador para pasar a subscribeOn()
y observeOn()
. Sería mejor darles nombres más significativos dado lo que representan, por ejemplo, "backgroundScheduler" y "uiScheduler"
- El uso de MultiDex en Android App ejecuta ProGuard dos veces y sólo segunda vez con Advertencias / Notas?
- Android – vistas de servicio