RxJava2 JUnit testing

1.8k views Asked by At

I have some troubles with unit testing a RxJava code part. I want to test the method below. It is a presenter method.

public void onSearchQueryChanged(String searchQuery) {
    backendService.getShopResultsCount(searchQuery)
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(result -> {
            if (isViewAttached()) {
                getView().hideShopSearchInProgress();
                getView().displayShopSearchResultCount(result.getSearchResponse().getNumberOfHits());
            }
        }, error -> {
            if (isViewAttached()) {
                getView().hideShopSearchInProgress();
            }
        });
}

In the best case I would like to mock the backendService and test this usecase for specific search queries and with attached/detached view.

I've done some research and I'm aware of toBlocking() and test() methods. They all assume I have the Observable available. I guess I have to split the method somehow. What would be your approach on that?

My stack: RxJava2, dagger, MVP.

2

There are 2 answers

0
Сергей Боиштян On BEST ANSWER

In our project we write code like:

Mockito.when(backendService.getShopResult(Mockito.any())).thenReturn(Observable.just(Some Data)

U can workaround schedulers by:

@Inject
Scheduler subscribeOn;

And in test pass Schedulers.test() or Schedulers.immediate()

or u cant use TestRule with RxJavaPlugins.registerSchedulersHook()

1
R. Zagórski On

First of all if this is a real MVP project, then you should have backendService and view somehow injected into presenter. So you can mock them with Mockito. @СергейБоиштян has provided the way how to do it and how to override Schedulers.

Definitely you should test which method of view is called when controlling backendService behaviour. That is to be done by Mockito.verify(...)

You might also test what output from backendService.getShopResultsCount(searchQuery) is passed to view by using Mockito's ArgumentCaptor