novoda / rxpresso

Easy Espresso UI testing for Android applications using RxJava.
Other
363 stars 23 forks source link

ClassCastException when RxPresso emits items #12

Closed fcavedon closed 2 years ago

fcavedon commented 8 years ago

I'm currently trying to use RxPresso in a test case, but it always gives a ClassCastException when the mock item is emitted.

Test class

@Rule
    public ActivityTestRule<SubDepartmentActivity> subDepartmentActivityActivityTestRule = new ActivityTestRule<SubDepartmentActivity>(SubDepartmentActivity.class) {
        @Override
        protected void beforeActivityLaunched() {
            metricsComponent = mock(MetricsComponent.class);
            networkComponent = mock(NetworkComponent.class);
            dataSourceComponent = mock(DataSourceComponent.class);
            departmentDataSource = mock(DepartmentDataSource.class);

            when(metricsComponent.getMetricsManager()).thenReturn(new MetricsManager());             when(dataSourceComponent.getDepartmentDataSource()).thenReturn(departmentDataSource);

            ((BaseApplication) InstrumentationRegistry.getTargetContext()
                    .getApplicationContext())
                    .setInjectorComponent(
                            DaggerInjectorComponent.builder()
                                    .metricsComponent(metricsComponent)
                                    .networkComponent(networkComponent)
                                    .dataSourceComponent(dataSourceComponent)
                                    .build());

            rxPresso = RxPresso.from(departmentDataSource);
            registerIdlingResources(rxPresso);
        }

        @Override
        protected Intent getActivityIntent() {
            Intent intent = new Intent(Intent.ACTION_MAIN);
            intent.putExtra(Constants.Activity.Department.DEPARTMENT_ID, "abc123");
            intent.putExtra(Constants.Activity.ACTIVITY_TITLE, "title");

            return intent;
        }

        @Override
        protected void afterActivityFinished() {
            super.afterActivityFinished();

            unregisterIdlingResources(rxPresso);
            rxPresso.resetMocks();
        }
    };

    @Test
    public void test_click_subdepartment_should_open_child_department() {
        rxPresso.given(departmentDataSource.getDepartmentById("abc123"))
                .withEventsFrom(Observable.just(new Department("1", "dept title", false, new ArrayList<Department>())))
                .expect(RxExpect.any(Department.class))
                .thenOnView(withId(R.id.department_recycler_view))
                .perform(actionOnItemAtPosition(0, click()));

        matchToolbarTitle("dept title");
    }

Activity

...

getDepartmentDataSource()
.getDepartmentById(getIntent().getStringExtra(Constants.Activity.Department.DEPARTMENT_ID))
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .compose(this.<Department>bindToLifecycle())
                .subscribe(new Action1<Department>() {
                    @Override
                    public void call(Department department) {
                        attachViewModel(new DepartmentListViewModel(department));
                    }
                });

Where getDepartmentDataSource retrieves the injected mock using Dagger 2.

When the test runs, I always get the following exception:

java.lang.ClassCastException: rx.subjects.SubjectSubscriptionManager$State cannot be cast to rx.Notification
 at rx.internal.operators.OperatorDematerialize$1.onNext(OperatorDematerialize.java:48)
 at rx.internal.operators.NotificationLite.accept(NotificationLite.java:150)
 at rx.subjects.SubjectSubscriptionManager$SubjectObserver.accept(SubjectSubscriptionManager.java:318)
 at rx.subjects.SubjectSubscriptionManager$SubjectObserver.emitLoop(SubjectSubscriptionManager.java:291)
 at rx.subjects.SubjectSubscriptionManager$SubjectObserver.emitFirst(SubjectSubscriptionManager.java:270)
 at rx.subjects.ClearableBehaviorSubject$1.call(ClearableBehaviorSubject.java:103)
 at rx.subjects.ClearableBehaviorSubject$1.call(ClearableBehaviorSubject.java:99)
 at rx.subjects.SubjectSubscriptionManager.add(SubjectSubscriptionManager.java:100)
 at rx.subjects.SubjectSubscriptionManager.call(SubjectSubscriptionManager.java:60)
 at rx.subjects.SubjectSubscriptionManager.call(SubjectSubscriptionManager.java:35)
 at rx.Observable$2.call(Observable.java:162)
 at rx.Observable$2.call(Observable.java:154)
 at rx.Observable$2.call(Observable.java:162)
 at rx.Observable$2.call(Observable.java:154)
 at rx.Observable$2.call(Observable.java:162)
 at rx.Observable$2.call(Observable.java:154)
 at rx.Observable.unsafeSubscribe(Observable.java:8098)
 at rx.internal.operators.OperatorSubscribeOn$1$1.call(OperatorSubscribeOn.java:62)
 at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:55)
 at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:423)
 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)

Is there something missing here, a configuration perhaps?

Thanks!

juankysoriano commented 2 years ago

Closing as this repository is no longer under maintenance and it's about to be archived