I have the following method
go()
private Pair<String, String> mPair;
public void go() {
Observable.zip(
mApi.webCall(),
mApi.webCall2(),
new Func2<String, String, Pair<String, String>>() {
@Override
public Pair<String, String> call(String s, String s2) {
return new Pair(s, s2);
}
}
)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1<Pair<String, String>>() {
@Override
public void call(Pair<String, String> pair) {
mApi.webCall3(pair.first, pair.second);
}
});
}
Observable.zip()
Pair
go()
webCall()
webCall2()
webCall3(String, String)
Api
@Test
public void testGo() {
/* Given */
Api api = spy(new Api() {
@Override
public Observable<String> webCall() {
return Observable.just("First");
}
@Override
public Observable<String> webCall2() {
return Observable.just("second");
}
@Override
public void webCall3() {
}
});
Test test = new Test(api);
/* When */
test.go();
/* Then */
verify(api).webCall();
verify(api).webCall2();
verify(api).webCall3("First", "second");
}
RxJavaSchedulersHook
RxAndroidSchedulersHook
Schedulers.immediate()
go()
I have found out that I can retrieve my Schedulers
in a non-static way, basically injecting them into my client class. The SchedulerProvider
replaces the static calls to Schedulers.x()
:
public interface SchedulerProvider {
Scheduler io();
Scheduler mainThread();
}
The production implementation delegates back to Schedulers
:
public class SchedulerProviderImpl implements SchedulerProvider {
public static final SchedulerProvider INSTANCE = new SchedulerProviderImpl();
@Override
public Scheduler io() {
return Schedulers.io();
}
@Override
public Scheduler mainThread() {
return AndroidSchedulers.mainThread();
}
}
However, during tests I can create a TestSchedulerProvider
:
public class TestSchedulerProvider implements SchedulerProvider {
private final TestScheduler mIOScheduler = new TestScheduler();
private final TestScheduler mMainThreadScheduler = new TestScheduler();
@Override
public TestScheduler io() {
return mIOScheduler;
}
@Override
public TestScheduler mainThread() {
return mMainThreadScheduler;
}
}
Now I can inject the SchedulerProvider
in to the Test
class containing the go()
method:
class Test {
/* ... */
Test(Api api, SchedulerProvider schedulerProvider) {
mApi = api;
mSchedulerProvider = schedulerProvider;
}
void go() {
Observable.zip(
mApi.webCall(),
mApi.webCall2(),
new Func2<String, String, Pair<String, String>>() {
@Override
public Pair<String, String> call(String s, String s2) {
return new Pair(s, s2);
}
}
)
.subscribeOn(mSchedulerProvider.io())
.observeOn(mSchedulerProvider.mainThread())
.subscribe(new Action1<Pair<String, String>>() {
@Override
public void call(Pair<String, String> pair) {
mApi.webCall3(pair.first, pair.second);
}
});
}
}
Testing this works as follows:
@Test
public void testGo() {
/* Given */
TestSchedulerProvider testSchedulerProvider = new TestSchedulerProvider();
Api api = spy(new Api() {
@Override
public Observable<String> webCall() {
return Observable.just("First");
}
@Override
public Observable<String> webCall2() {
return Observable.just("second");
}
@Override
public void webCall3() {
}
});
Test test = new Test(api, testSchedulerProvider);
/* When */
test.go();
testSchedulerProvider.io().triggerActions();
testSchedulerProvider.mainThread().triggerActions();
/* Then */
verify(api).webCall();
verify(api).webCall2();
verify(api).webCall3("First", "second");
}