how to test the server call with Mockito, Retrofit and RxJava

how to test the server call with Mockito, Retrofit and RxJava

In this example you can learn how to test server call with Mockito and RxJava
1. Service
2. ServiceInteractor
3. ServiceInteractorTest

Simple Service:

public interface Service {
    String URL_BASE = "https://guessthebeach.herokuapp.com/api/";

    @GET("topics/")
    Observable<List<Topics>> getTopicsRx();

}

For ServiceInteractor

public class ServiceInteractor {
    private LruCache<String, List<Topics>> cache;
    private Service service;

    public ServiceInteractor(Retrofit retrofit, LruCache<String, List<Topics>> cache) {
        this.cache = cache;
        this.service = retrofit.create(Service.class);
    }

    public Observable<List<Topics>> searchUsers() {
        return Observable.concat(cachedResults(), networkResults()).first();
    }

    private Observable<List<Topics>> cachedResults() {
        return Observable.just(cache.get("query"))
                .filter((List<Topics> result) ->
                        result != null
                );
    }

    private Observable<List<Topics>> networkResults() {
        return service.getTopicsRx()
                .doOnNext((List<Topics> result) ->
                        cache.put("query", result));
    }
}
 

The key is MockWebServer from okhttp3.

This library makes it easy to test that your app Does The Right Thing when it makes HTTP and HTTPS calls. It lets you specify which responses to return and then verify that requests were made as expected.

Because it exercises your full HTTP stack, you can be confident that you’re testing everything. You can even copy & paste HTTP responses from your real web server to create representative test cases. Or test that your code survives in awkward-to-reproduce situations like 500 errors or slow-loading responses.

Use MockWebServer the same way that you use mocking frameworks like Mockito:

  1. Script the mocks.
  2. Run application code.
  3. Verify that the expected requests were made.

Here’s a complete example in ServiceInteractorTest:

 

public class ServiceInteractorTest {
    @Mock
    private LruCache<String, List<Topics>> mCache;

    @Before
    public void setup(){

        MockitoAnnotations.initMocks(this);
        when(mCache.get(anyString())).thenReturn(null);
    }

    @Test
    public void mockServiceTest() {

        Topics topics = new Topics(1, "football");

        List<Topics> result = new ArrayList();

        result.add(topics);

        MockWebServer mockService = new MockWebServer();
        mockService.enqueue(new MockResponse().setBody(new Gson().toJson(result)));

        Retrofit retrofit = new Retrofit.Builder()
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                .addConverterFactory(GsonConverterFactory.create())
                .baseUrl(mockService.url("dfdf/"))
                .build();

        TestSubscriber<List<Topics>> subscriber = new TestSubscriber<>();
        ServiceInteractor serviceInteractor = new ServiceInteractor(retrofit, mCache);
        serviceInteractor.searchUsers().subscribe(subscriber);

        subscriber.assertNoErrors();
        subscriber.assertCompleted();
    }

    @Test
    public void callServiceTest() {
        Topics topics = new Topics(1, "Discern The Beach");
        Topics topicsTwo = new Topics(2, "Discern The Football Player");

        List<Topics> result = new ArrayList();
        result.add(topics);
        result.add(topicsTwo);

        MockWebServer mockWebServer = new MockWebServer();
        mockWebServer.enqueue(new MockResponse().setBody(new Gson().toJson(result)));

        Retrofit retrofit = new Retrofit.Builder()
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                .addConverterFactory(GsonConverterFactory.create())
                .baseUrl(mockWebServer.url("https://guessthebeach.herokuapp.com/api/"))
                .build();

        TestSubscriber<List<Topics>> subscriber = new TestSubscriber<>();
        ServiceInteractor serviceInteractor = new ServiceInteractor(retrofit, mCache);
        serviceInteractor.searchUsers().subscribe(subscriber);

        subscriber.assertNoErrors();
        subscriber.assertCompleted();
    }


}

 

You can check my example in GitHub

Learn RxJava

Learn RxJava

In this example you can understand different elements of RxJava with Strings.

Simple
This method creates an Observable such that when an Observer subscribes, the onNext() of the Observer is immediately called with the argument provided to Observable.just(). The onCompleted() will then be called since the Observable has no other values to emit.

Observable.create(subcriber ->{
        subcriber.onNext("Hello");
        subcriber.onNext("Javier Gonzalez");
        subcriber.onCompleated();
    });

Now with Exception:

    Observable.create(subcriber ->{
        subcriber.onNext("Hello");
        subcriber.onNext("Javier Gonzalez");
        subcriber.onError(new Exception("iOS user now allowed"));
    });

And there are another different ways to do:

    Observable.just("Hello again...");

    Observable.from(Arrays.asList("Hello", "again..."));

    Observable.from(new String[]{"Hello", "again..."});

    Observable.concat(Observable.just("Hello"), Observable.just("again..."));

    Observable.merge(Observable.just("Hello", "again..."), Observable.never());

Also you can check this example
And this post

RxJava retrolambda

RxJava retrolambda

This is a example how to use RxJava and Retrolambda on Android.
You can see the complete example in GitHub

Web Launcher

Java 8 introduced Lambdas Expressions, unfortunately Android does not support Java 8, so we are not able to take advantage of this with RxJava. Luckily there is a library called Retrolambda which backports lambdas to previous versions of Java. There is also a gradle plugin for Retrolambda that will allow the use of lambdas in an Android application.

In RxJava there are different elements:

1.BASIC(Observable)

2.ASYNCHRONOUS

3.SINGLES

4.SUBJECTS

5.MAP

6.DEBOUNCES

Basic

This method creates an Observable such that when an Observer subscribes, the onNext() of the Observer is immediately called with the argument provided to Observable.just(). The onCompleted() will then be called since the Observable has no other values to emit:

    Observable<List<String>> listObservable = Observable.just(getColorList());

    listObservable.subscribe(new Observer<List<String>>() { 

            @Override 
            public void onCompleted() { } 

            @Override 
            public void onError(Throwable e) { } 

            @Override
            public void onNext(List<String> colors) {
                mSimpleStringAdapter.setStrings(colors);
            }
    });

with lambda:

    Observable<List<String>> listObservable = Observable.just(getColorList());

    listObservable.subscribe(
                (List<String> colors)-> mSimpleStringAdapter.setStrings(colors),
                (error) -> {},
                () -> {});

Asynchronous

If we use it with Observable.just(), mRestClient.getFavoriteTvShows() will be evaluated immediately and block the UI thread. Enter the Observable.fromCallable() method. It gives us two important things: * The code for creating the emitted value is not run until someone subscribes to the Observer. * The creation code can be run on a different thread.

    Observable<List<String>> tvShowObservable = Observable.fromCallable(new Callable<List<String>>() { 

        @Override 
        public List<String> call() { 
            return mRestClient.getFavoriteTvShows(); 
        }
    });

    mTvShowSubscription = tvShowObservable
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(
                        new Observer<List<String>>() {
                            @Override
                            public void onCompleted() {

                            }

                            @Override
                            public void onError(Throwable e) {

                            }

                            @Override
                            public void onNext(List<String> tvShows) {
                                displayTvShows(tvShows);
                            }
                        });

with lambda:

    Observable<List<String>> tvShowObservable = Observable.fromCallable(() -> mRestClient.getFavoriteTvShows());
    mTvShowSubscription = tvShowObservable
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(
                (List<String> tvShows) -> displayTvShows(tvShows),
                (error) -> {},
                () -> {});

Singles

There’s a simpler version of an Observable called a Single. Singles work almost exactly the same as Observables. But instead of there being an onCompleted(), onNext(), and onError(), there are only two callbacks: * onSuccess() and onError().

    Single<List<String>> tvShowSingle = Single.fromCallable(new Callable<List<String>>() { 

        @Override
        public List<String> call() throws Exception {
            mRestClient.getFavoriteTvShows(); 
        }
    });

    mTvShowSubscription = tvShowSingle
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new SingleSubscriber<List<String>>() {
                    @Override
                    public void onSuccess(List<String> tvShows) {
                        displayTvShows(tvShows);
                    }

                    @Override
                    public void onError(Throwable error) {
                        displayErrorMessage();
                    }
                }); 

with lambda:

    Single<List<String>> tvShowSingle = Single.fromCallable(() -> mRestClient.getFavoriteTvShows());

    mTvShowSubscription = tvShowSingle
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe((List<String> tvShows) -> displayTvShows(tvShows),
                    (Throwable error) ->  displayErrorMessage());

Subjects

Subjects are special objects that are both an Observable and an Observer. With a PublishSubject, as soon as you put something in one end of the pipe it immediately comes out the other.

    PublishSubject<Integer> mCounterEmitter = PublishSubject.create();
    mCounterEmitter.subscribe(new Observer<Integer>() {
            @Override
            public void onCompleted() {

            }

            @Override
            public void onError(Throwable e) {

            }

            @Override
            public void onNext(Integer integer) {
                mCounterDisplay.setText(String.valueOf(integer));
            }
        });

with lambda:

    PublishSubject<Integer>  mCounterEmitter = PublishSubject.create();
    mCounterEmitter.subscribe(
                (Integer integer) ->  mCounterDisplay.setText(String.valueOf(integer)),
                (Throwable e) ->{},
                () -> { });

It increments a variable called mCounter. It calls onNext() on the mCounterEmitter with the new value of mCounter.

    mCounter ++;
    mCounterEmitter.onNext(mCounter);

Map

It’s a function that takes in one value and outputs another value. Usually there is some relationship between value put in to the map and the value that is output.

    Single.just(4).map(new Func1<Integer, String>() { 

        @Override 
        public String call(Integer integer) { 
            return String.valueOf(integer);
        } 
    }).subscribe(new SingleSubscriber<String>() { 

        @Override 
        public void onSuccess(String value) { 
            mValueDisplay.setText(value); 
        } 

        @Override 
        public void onError(Throwable error) { } 
        });

with lambda:

    Single.just(4).map((Integer integer) -> String.valueOf(integer))

                .subscribe((String value) -> mValueDisplay.setText(value),
                        (Throwable error) -> {});

Debounce

Everything together and a new concept: debounce. Let’s dive in. If you want to setup a PublishSubject such that it receives values the user types into a search box, fetches a list of suggestions based on that query, and then displays them.

    mSearchResultsSubject = PublishSubject.create();
    mTextWatchSubscription = mSearchResultsSubject
        .debounce(400, TimeUnit.MILLISECONDS)
        .observeOn(Schedulers.io())
        .map(new Func1<String, List<String>>() {

            @Override 
            public List<String> call(String s) { 
                return mRestClient.searchForCity(s); 
            } 
        })
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(new Observer<List<String>>() { 

            @Override 
            public void onCompleted() { }

            @Override 
            public void onError(Throwable e) { } 

            @Override
            public void onNext(List<String> cities) {
                handleSearchResults(cities); 
            }
        });
    });

with lambda:

    mSearchResultsSubject = PublishSubject.create();
    mTextWatchSubscription = mSearchResultsSubject
                .debounce(400, TimeUnit.MILLISECONDS)
                .observeOn(Schedulers.io())
                .map( (String string) -> mRestClient.searchForCity(string))
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe((List<String> cities) -> handleSearchResults(cities),
                        (Throwable e) -> {},
                        () -> {});

Libraries

The project is setup using:

You can see the complete example in GitHub

As the above only gives a rough overview of rxjava example I’d strongly recommend checking out the following: