Checking communication between rxjava subscribers

To depict a situation in an MVP template where your presenter subscribes to a service that returns an observer:

public void gatherData(){
   service.doSomeMagic()
      .observeOn(Schedulers.io())
      .subscribeOn(AndroidSchedulers.mainThread())
      .subscribe(new TheSubscriber());
}

      

Now the class TheSubscriber

calls the onNext

method from the view, for example:

@Override public void onNext(ReturnValue value) {
  view.displayWhatever(value);
}

      

Now, in my unit test, I would like to check that when the method is called gatherData()

in a non-error situation, the view method is displayWhatever(value)

called.

Question :

Is there a clean way to do this?

Background

  • I use mockito to test interactions and of course, much more.
  • The dagger enters the entire presenter except TheSubscriber

What I have tried :

  • Introduce a subscriber and make fun of him in tests. I find it a little messy because if I want to change the way the presenter interacts with a service (say, not Rx), I need to change a lot of tests and code.
  • Fool the whole service. It wasn't that bad, but I had a lot of methods to mock and I didn't quite get to what I wanted.
  • Looked on the internet but no one seems to have a straight forward way to do this.

thanks for the help

+3


source to share


2 answers


Assuming you are using interfaces for service

and in a view

similar manner:

class Presenter{
  Service service;
  View view;

  Presenter(Service service){
    this.service = service;
  }

  void bindView(View view){
    this.view = view;
  }

  void gatherData(){
    service.doSomeMagic()
      .observeOn(Schedulers.io())
      .subscribeOn(AndroidSchedulers.mainThread())
      .subscribe(view::displayValue);
  }
}

      



Then you can mock to monitor and test the behavior:

@Test void assert_that_displayValue_is_called(){
  Service service = mock(Service.class);
  View view = mock(View.class);
  when(service.doSomeMagic()).thenReturn(Observable.just("myvalue"));
  Presenter presenter = new Presenter(service);
  presenter.bindView(view);

  presenter.gatherData();

  verify(view).displayValue("myvalue");
}

      

+6


source


I know its quite late, but can it help someone because I have been looking for quite a while for a solution to your question: D

For me it worked out to add Observable.Transformer<T, T>

as follows:

    void gatherData() {
        service.doSomeMagic()
          .compose(getSchedulerTransformer())
          .subscribe(view::displayValue);
    }

    private <T> Observable.Transformer<T, T> getSchedulerTransformer() {
        if (mTransformer == null) {
            mTransformer = (Observable.Transformer<T, T>) observable -> observable.subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread());
        }

        return mTransformer;
    }

    void setSchedulerTransformer(Observable.Transformer<Observable<?>, Observable<?>> transformer) {
        mTransformer = transformer;
    }

      

And to install Transformer just I just passed this:



setSchedulerTransformer(observable -> {
            if (observable instanceof Observable) {
                Observable observable1 = (Observable) observable;
                return observable1.subscribeOn(Schedulers.immediate())
                        .observeOn(Schedulers.immediate());
            }
            return null;
        });

      

So just add a method @Before

to your test and call presenter.setSchedulerTransformer

and it should check it :)

hope this helps and is somehow clear: D

+2


source







All Articles