Search code examples
unit-testingrx-javaandroid-testingrx-android

JUnit Scheduler that doesn't depend on Android


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?


Solution

  • 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?