0
votes

I was watching some videos about switching to MVP, RX Java and writing tests before that... so basically TDD.. anyway, guys that were writing those Presenters and tests for that presenter, had an issue.

Here's what they did. They were using Rx Java for returning the Observables from database and inside their presenter they had the method and they called operators .subscribeOn(Schedulers.io) and .observeOn(AndroidSchedulers.mainThread)

So the test failed because it runs on one thread, and sometimes method on view (on mainThread) doesn't get called... I didn't understand it well ... maybe someone knows what I'm trying to say

My question is, can you do it this way (does it solve the problem)? This is the method from my presenter:

@Override
    public void getRandomJoke() {
        mJokeView.showProgress();
        jokeInteractor.getRandomJoke()
                .subscribe(new Observer<RandomJokeResponse>() {
                @Override
                public void onCompleted() {
                    mJokeView.hideProgress();
                    mJokeView.showJoke(mJoke);
                }

                @Override
                public void onError(Throwable e) {
                    mJokeView.hideProgress();
                    mJokeView.showError(e.getMessage());
                }

                @Override
                public void onNext(RandomJokeResponse randomJokeResponse) {
                    if (randomJokeResponse != null) {
                        mJokeView.hideProgress();
                        mJoke = randomJokeResponse.getJokeData().getJoke();
                    }
                }
            });

}

and I put those two operators inside my interactor:

    @Override
    public Observable<RandomJokeResponse> getRandomJoke() {
        return retrofitService.getRandomJoke()
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

I still haven't got to write tests, just started watching videos and saw that issue, so now I wonder is this a good idea to do it this way, since I've heard you shouldn't have anything related to Android inside your presenter...because of testing...

1
That looks nice for me. Have you test it? BTW, check this line if (randomJokeResponse != null), maybe randomJokeResponse is never null and it's just defensive programming (bad practice)Héctor
Tnx! ..it shouldn't be null since this is observable, you are not pulling, so if it has a response you'll get it, right? ...I still didn't write a single line of test :) just started watching videos and I saw that guys encountered that problem with threads in presenter. And the way they fixed it is to pass Schedulers from activity to presenter and in test they used Schedulers.trampoline in Before annotation. Not really sure what was the issue, so I wanted to ask if someone knows what's the issue there and if my solution fixes that issuejoe
True, if you are using retrofit, it will never emit a null value. Problem is that network access should be in a io thread and change de UI should be in mainThread, but in the test you may not have the Android thread (it's not an Android test) so you need to enqueue the work, instead of delegate it to main (Android) thread.Héctor
Exactly, that's a good approachHéctor
Glad to hear that! :) tnx!joe

1 Answers

0
votes

I use to hadnle my schedulers as external dependencies inside my presenter so I can just inject Schedulers.immediate() on my tests so they will perform synchronously.