I´m trying to use MVP to enhance unit testing and run tests faster (because I'm testing logic not android code so I avoid using things like RobotElectric).
But I´m using RXAndroid and it needs Looper to get Schedulers.io()
and AndroidSchedulers.mainThread()
and when I try to run sometime like
class Phone {
public Observable<> sendSms(String number){
//...
}
}
Phone.getInstance().sendSms(phoneNumber)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(phone -> {
mView.dismissProgress();
mView.startCodeView(phone);
}, error -> {
mView.dismissProgress();
mView.showError(error);
});
I get:
Caused by: java.lang.RuntimeException: Method getMainLooper in android.os.Looper not mocked. See http://g.co/androidstudio/not-mocked for details.
at android.os.Looper.getMainLooper(Looper.java)
at rx.android.schedulers.AndroidSchedulers.<clinit>(AndroidSchedulers.java:27)
... 28 more
I tried:
android {
// ...
testOptions {
unitTests.returnDefaultValues = true
}
}
But it will not work because I want to run full JUnit tests and not Roboelectric or Espresso stuff.
How can I accomplish it? is there any Scheduler that will not crash because of this?
I am also using scheduler thread for this, but in my test SetUp and TearDown.
@Before
public void setUp() throws Exception {
RxAndroidPlugins.getInstance().registerSchedulersHook(new RxAndroidSchedulersHook() {
@Override
public Scheduler getMainThreadScheduler() {
return Schedulers.immediate();
}
});
}
@After
public void tearDown() {
RxAndroidPlugins.getInstance().reset();
}
Will this help?
I ended up adding using transformations and "flavour injection classes" for this, have a class that uses the main for prod/debug releases and use another class in the test flavour folder for testing Schedulers.immediate()
.
normal flavoured class:
public class Transformer {
public static <T> Observable.Transformer<T, T> applyIoSchedulers() {
return observable -> observable.subscribeOn(getIoScheduler())
.observeOn(getMainScheduler());
}
private static Scheduler getIoScheduler() {
return Schedulers.io();
}
private static Scheduler getMainScheduler() {
return AndroidSchedulers.mainThread();
}
}
Testing flavoured class:
public class Transformer {
public static <T> Observable.Transformer<T, T> applyIoSchedulers() {
return observable -> observable.subscribeOn(getIoScheduler())
.observeOn(getMainScheduler());
}
private static Scheduler getIoScheduler() {
return Schedulers.immediate() ;
}
private static Scheduler getMainScheduler() {
return Schedulers.immediate() ;
}
}
Then use it with transformations:
mSessionRepository.login(...)
.compose(Transformer.applyIoSchedulers())
.subscribe(session -> { })
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