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.

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 🙂

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"

  • Acceso al dominio desde un subproceso incorrecto Excepción mientras se envió una copia usando copyFromRealm
  • ¿Por qué necesita onBackpressure () aquí para eventos de clic?
  • Filtrar lista de objetos en Rxjava
  • ¿Cómo rebatir una solicitud reactiva retrofit en java?
  • RxJava Observable a Completable, cómo evitar toBlocking ()
  • Utilizando RxJava para buscar objetos, transforma una lista contenedora y usa la lista
  • MVP de Android con RxAndroid + Retrofit
  • Android + RxJava - carga de datos de db y servicio web
  • Excepción de interrupción de subproceso en modo Multi-ventana
  • Cómo poner en cola las llamadas de la API cuando no está conectado mientras usa Retrofit
  • Realizar N llamadas de api secuenciales usando RxJava y Retrofit
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.