I have successfully created a custom espresso test runner which looks like this:
public class PomeloTestRunner extends AndroidJUnitRunner {
@Override
public void onCreate(Bundle arguments) {
RxJavaPlugins.setInitComputationSchedulerHandler(
Rx2Idler.create("RxJava 2.x Computation Scheduler"));
RxJavaPlugins.setInitIoSchedulerHandler(Rx2Idler.create("RxJava 2.x Computation Scheduler"));
RxJavaPlugins.setInitNewThreadSchedulerHandler(Rx2Idler.create("RxJava 2.x Computation Scheduler"));
RxJavaPlugins.setInitSingleSchedulerHandler(Rx2Idler.create("RxJava 2.x Computation Scheduler"));
super.onCreate(arguments);
}
}
my network layer of my application is written in rxjava2 so and I needed a way to link the espresso scheduling with rxjava so I chose to use Rx2Idler
but the problem I am getting is that when I run my tests I am getting the following error:
FATAL EXCEPTION: RxCachedThreadScheduler-1
Process: com.mobile.pomelo.labs, PID: 11611
java.lang.NullPointerException: Attempt to invoke interface method 'void android.support.test.espresso.IdlingResource$ResourceCallback.onTransitionToIdle()' on a null object reference
at com.squareup.rx2.idler.DelegatingIdlingResourceScheduler.stopWork(DelegatingIdlingResourceScheduler.java:96)
at com.squareup.rx2.idler.DelegatingIdlingResourceScheduler$ScheduledWork.run(DelegatingIdlingResourceScheduler.java:142)
at io.reactivex.internal.schedulers.ScheduledRunnable.run(ScheduledRunnable.java:61)
at io.reactivex.internal.schedulers.ScheduledRunnable.call(ScheduledRunnable.java:52)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:269)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
at java.lang.Thread.run(Thread.java:818)
here is my actual test if it's of any importance. the test fails but if I remove the scheduler overrides it works with the sleep:
@RunWith(AndroidJUnit4.class)
public class AuthenticationActivityTest {
@Before
public void setUp() throws Exception {
mIntentsTestRule.getActivity().sharedPrefRepo.clearAll();
}
@Rule
public IntentsTestRule<AuthenticationActivity> mIntentsTestRule =
new IntentsTestRule<AuthenticationActivity>(AuthenticationActivity.class) {
@Override
protected Intent getActivityIntent() {
Context targetContext = InstrumentationRegistry.getInstrumentation()
.getTargetContext();
Intent result = new Intent(targetContext, AuthenticationActivity.class);
Bundle b = new Bundle();
b.putSerializable("action", AuthenticationActivity.LoginActions.LOGIN);
result.putExtras(b);
return result;
}
};
@Test
public void signupWithFacebook() {
final Intent resultData = new Intent();
resultData.putExtra("com.facebook.LoginFragment:Result", LoginClientCreator.createResult());
intending(hasComponent(FacebookActivity.class.getName()))
.respondWith(new Instrumentation.ActivityResult(Activity.RESULT_OK, resultData));
// click signup fb button
onView(withId(R.id.fb_login_button))
.perform(click());
// check facebook intent was hit
intended(hasComponent(FacebookActivity.class.getName()), times(1));
try {
Thread.sleep(14000); // i dont want this to sleep, i would rather the espresso idle sync work with rxjava2
} catch (InterruptedException e) {
e.printStackTrace();
}
ViewInteraction appCompatTextView = onView(allOf(withText("COLLECTIONS"), isDisplayed()));
appCompatTextView.perform(click());
}
}
also take note that all my rxjava calls look like the following:
public void execute(@NonNull Observer UseCaseSubscriber){
this.buildUseCaseObservable()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(UseCaseSubscriber);
}
update: i am wondering if its the firebase network calls which are not idle synced. these calls are not using rxjava so could they be not handled by Rx2Idler ?
I tried various options like setup RxJava plugins in onCreate()
of Test Runner class, or registering ResourceCallback on all resources.
But solution worked for me is just setting up RxJavaPlugins after super.onStart()
Please check code here:
public class AppTestRunner extends AndroidJUnitRunner {
@Override
public void onStart() {
super.onStart();
setupRxJavaPlugins();
}
private void setupRxJavaPlugins() {
// rx-java 2
RxJavaPlugins.setInitComputationSchedulerHandler(Rx2Idler.create("RxJava 2.x Computation Scheduler"));
RxJavaPlugins.setInitIoSchedulerHandler(Rx2Idler.create("RxJava 2.x IO Scheduler"));
RxJavaPlugins.setInitNewThreadSchedulerHandler(Rx2Idler.create("RxJava 2.x NewThread Scheduler"));
RxJavaPlugins.setInitSingleSchedulerHandler(Rx2Idler.create("RxJava 2.x Single Scheduler"));
// rx-java 1
rx.plugins.RxJavaPlugins.getInstance().registerSchedulersHook(RxIdler.hooks());
}
}
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