Reputation: 181
I'm trying to migrate my app to work with RxJava. I already use Retrofit and therefore I'm trying to use a Retrofit interface which methods return Observables. However I'm now having issues with coding tests against it, as I can't get the Observable to run on the main thread; I'm trying to use Scheduler.immediate() for it. It seems that Retrofit doesn't allow to override it's behaviour, which makes totally sense for the real execution flow, but it makes testing very difficult. As I've just started with RxJava + Retrofit I just hope I'm doing something wrong instead.
Below is what the code looks like:
@Test
public void shouldCompleteRequest() {
SomeRestRequest request = new SomeRestRequest(arg1, arg2);
TestSubscriber<SomeRestResponse> testSubscriber = new TestSubscriber<>();
new SomeRestCommand(mRestApi,
arg1, arg2
Schedulers.immediate(),
Schedulers.immediate(),
mMockEventBus).execute(request, testSubscriber);
testSubscriber.assertCompleted();
}
where
public void execute(T request, Observer<S> observer) {
getCommand(request)
.observeOn(mObserveOnScheduler) //The test injects Schedulers.immediate()
.subscribeOn(mSubscribeOnScheduler) //The test injects Schedulers.immediate()
.subscribe(observer);
}
,
@Override
protected Observable<SomeRestResponse> getCommand(SomeRestRequest request) {
return mRestApi.restCommand(arg1, arg2);
}
and
public interface RestApi {
@GET("/someEndPoint")
Observable<SomeRestResponse> restCommand(@Query("arg1") String arg1, @Query("arg2") String arg2);
}
Upvotes: 3
Views: 3070
Reputation: 4010
If you modify your test to add testSubscriber.awaitTerminalEvent();
, then your test will wait for the call to complete and hence the test will pass. You will still have to do an assertCompleted()
as the terminal event can be either of successful completion or error.
@Test
public void shouldCompleteRequest() {
SomeRestRequest request = new SomeRestRequest(arg1, arg2);
TestSubscriber<SomeRestResponse> testSubscriber = new TestSubscriber<>();
new SomeRestCommand(mRestApi,
arg1, arg2
Schedulers.immediate(),
Schedulers.immediate(),
mMockEventBus).execute(request, testSubscriber);
testSubscriber.awaitTerminalEvent(); // add this line here
testSubscriber.assertCompleted();
}
I looked up the source code of Retrofit 1.9.0 and as per RxSupport
class, the call is always executed in a separate thread provided by the httpExecutor
. Hence using Schedulers.immediate()
did not cause the call to happen in the main thread.
Upvotes: 5