I am writing a unit test and need to mock an Observable (from retrofit)
The code in the tested component is as follows:
getApiRequestObservable()
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io())
.subscribe(...)
In the unit test (against the JVM so AndroidSchedulers
are not available) I need to make it all synchronous so my tests will look like:
@Test
public void testSomething() {
doReturn(mockedResponse).when(presenter).getApiRequestObservable();
presenter.callApi();
verify(object,times(1)).someMethod();
}
To do this, I should register hooks in a setUp() method:
@Before
public void setUp() throws Exception {
// AndroidSchedulers.mainThread() is not available here so we fake it with this hook
RxAndroidPlugins.getInstance().registerSchedulersHook(new RxAndroidSchedulersHook() {
@Override
public Scheduler getMainThreadScheduler() {
return Schedulers.immediate();
}
});
// We want synchronous operations
RxJavaPlugins.getInstance().registerSchedulersHook(new RxJavaSchedulersHook(){
@Override
public Scheduler getIOScheduler() {
return Schedulers.immediate();
}
});
}
But this throws the above exception as I am apparently not allowed to register two hooks. Is there any way around that?
The problem is that you're not resetting test state - you can verify that by running single test. To fix your particular problem you need to reset
rx plugins state like so:
@Before
public void setUp(){
RxJavaPlugins.getInstance().reset();
RxAndroidPlugins.getInstance().reset();
//continue setup
...
}
You can even wrap the reset into a reusable @Rule
as described by Alexis Mas blog post:
public class RxJavaResetRule implements TestRule {
@Override
public Statement apply(Statement base, Description description) {
return new Statement() {
@Override
public void evaluate() throws Throwable {
//before: plugins reset, execution and schedulers hook defined
RxJavaPlugins.getInstance().reset();
RxAndroidPlugins.getInstance().reset();
// register custom schedulers
...
base.evaluate();
}
};
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With