Unit testing retrofit RxJava

Unit testing retrofit RxJava

ReactiveX is a combination of the best ideas from the Observer pattern, the Iterator pattern, and functional programming.

RxAndroid is an extension to RxJava. It providers a scheduler to run code in the main thread of Android. It also provides the ability to create a scheduler that runs on a Android handler class. With this schedulers, you can define an observable which does its work in a background thread, and post our results to the main thread. This allows for example to replace a AsyncTask implementations which RxJava.

The subscriber observes in the main thread
Observable is called outside the main thread

To manage RxJava is not so difficult, When we have to use RxJava in Unit test, We need to create these element:

1. BaseSchedulerProvider (Father)
2. ImmediateSchedulerProvider (Testing)
3. SchedulerProvider (Application)

Android Test, Unit testing retrofit RxJava
You can check my complete example in GitHub

BaseSchedulerProvider :

public interface BaseSchedulerProvider {

    @NonNull
    Scheduler computation();

    @NonNull
    Scheduler io();

    @NonNull
    Scheduler ui();
}

ImmediateSchedulerProvider I use for a test:

public class ImmediateSchedulerProvider implements BaseSchedulerProvider {

    @NonNull
    @Override
    public Scheduler computation() {
        return Schedulers.immediate();
    }

    @NonNull
    @Override
    public Scheduler io() {
        return Schedulers.immediate();
    }

    @NonNull
    @Override
    public Scheduler ui() {
        return Schedulers.immediate();
    }
}

And SchedulerProvider I use in my Presenter

public class SchedulerProvider implements BaseSchedulerProvider {

    // Prevent direct instantiation.
    public SchedulerProvider() {
    }

    @Override
    @NonNull
    public Scheduler computation() {
        return Schedulers.computation();
    }

    @Override
    @NonNull
    public Scheduler io() {
        return Schedulers.io();
    }

    @Override
    @NonNull
    public Scheduler ui() {
        return AndroidSchedulers.mainThread();
    }
}

In my PresenterTest I setUp like this:

public class TopicPresenterTest {

            @Mock
            private RemoteDataSource mRemoteDataSource;

            @Mock
            private TopicContract.View mView;

            private BaseSchedulerProvider mSchedulerProvider;

            TopicPresenter mPresenter;

            List<Topics> mList;

            @Before
            public void setup() {
            MockitoAnnotations.initMocks(this);

                    Topics topics = new Topics(1, "Discern The Beach");
                    Topics topicsTwo = new Topics(2, "Discern The Football Player");
                    mList = new ArrayList<>();
                    mList.add(topics);
                    mList.add(topicsTwo);
//ADD IMMEDIATESCHEDULERPROVIDER !!!!!!!!!!!!!!!
                    mSchedulerProvider = new 
                    ImmediateSchedulerProvider();

                    mPresenter = new TopicPresenter(mRemoteDataSource, mView, mSchedulerProvider);

            }

            @Test
            public void fetchData() {

                when(mRemoteDataSource.getTopicsRx())
                        .thenReturn(rx.Observable.just(mList));

                mThemePresenter.fetch();

                InOrder inOrder = Mockito.inOrder(mView);
                inOrder.verify(mView).setLoadingIndicator(false);
                inOrder.verify(mView).showTopics(mList);

            }

}

And In my Presenter I call to my server with retrofit:

public class TopicPresenter {

    @NonNull
    private BaseSchedulerProvider mSchedulerProvider;

    public TopicPresenter(@NonNull RemoteDataSource remoteDataSource, @NonNull TopicContract.View view) {
                    this.mRemoteDataSource = checkNotNull(remoteDataSource, "remoteDataSource");
                    this.mView = checkNotNull(view, "view cannot be null!");
                    this.mSchedulerProvider = new SchedulerProvider();
 //ADD COMPOSITESUBSCRITPTION !!!!!!     
                    mSubscriptions = new CompositeSubscription();

                    mView.setPresenter(this);
    }

    @Override
    public void fetch() {

        Subscription subscription = mRemoteDataSource.getTopicsRx()
                .subscribeOn(mSchedulerProvider.computation())
                .observeOn(mSchedulerProvider.ui())
                .subscribe((List<Topics> listTopics) -> {
                            mView.setLoadingIndicator(false);
                            mView.showTopics(listTopics);
                        },
                        (Throwable error) -> {
                            try {
                                mView.showError();
                            } catch (Throwable t) {
                                throw new IllegalThreadStateException();
                            }

                        },
                        () -> {
                        });

        mSubscriptions.add(subscription);
    }

    @Override
    public void subscribe() {
        fetch();
    }

    @Override
    public void unSubscribe() {
        mSubscriptions.clear();
    }


}

You can check my complete example in GitHub

Leave a Reply

Your email address will not be published. Required fields are marked *