【问题标题】:espresso custom TestRunner with RxJava2 - using Rx2Idler getting null pointer exception带有 RxJava2 的 espresso 自定义 TestRunner - 使用 Rx2Idler 获取空指针异常
【发布时间】:2017-10-16 12:05:00
【问题描述】:

我已经成功创建了一个自定义的 espresso 测试运行器,如下所示:

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);
    }
}

我的应用程序的网络层是用 rxjava2 编写的,所以我需要一种方法将 espresso 调度与 rxjava 链接起来,所以我选择使用Rx2Idler

但我遇到的问题是,当我运行测试时,出现以下错误:

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)

这是我的实际测试,如果它有任何重要性。测试失败,但如果我删除调度程序覆盖它与睡眠一起工作:

    @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());
    }
}

还要注意我所有的 rxjava 调用如下所示:

public void execute(@NonNull Observer UseCaseSubscriber){
                 this.buildUseCaseObservable()
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(UseCaseSubscriber);
    }

更新:我想知道它的 Firebase 网络调用是否没有空闲同步。这些调用没有使用 rxjava,所以它们不能由 Rx2Idler 处理吗?

【问题讨论】:

  • 您好!你解决了这个问题吗?

标签: android android-espresso square


【解决方案1】:

我尝试了各种选项,例如在 Test Runner 类的 onCreate() 中设置 RxJava 插件,或者在所有资源上注册 ResourceCallback。

但对我有用的解决方案只是在 super.onStart() 之后设置 RxJavaPlugins

请在此处查看代码:

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());
    }
}

【讨论】:

    猜你喜欢
    • 2018-01-24
    • 2013-03-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-01
    相关资源
    最近更新 更多