【问题标题】:RxJava: Asserts not workingRxJava:断言不起作用
【发布时间】:2017-01-31 17:56:48
【问题描述】:

我在使用 Robolectric 编写的单元测试中遇到了一些问题。问题是我正在测试一个UseCase,这个UseCase 使用rx.Observable 来执行异步任务,在内部它还调用另一个rx.Observable,它对一个非常大的集合进行排序。我已经在 UseCase 中注入了调度程序,我尝试使用Schedulers.immediate()new TestSceduler()AndroidSchedulers.mainThread()。似乎没有任何效果。这是执行流程:

...
@Test
public void testCacheConsistency() {
    AppComponent appComponent = getAppComponents(new EventList1MockRepository());
    injectFields(appComponent);

    //First we are going to request a list of events without using the cache
    getEventsInteractor.execute(new GetEvents.Callback() {
        @Override
        public void onEventsFetched(List<Event> eventList) {
            assertTrue(false); //This asserts should throw an exception
            assertEquals(42343, eventList.size());
        }

        @Override
        public void onCachedEventsFetched(List<Event> eventList) {
            assertFalse("This method shouldn't be called", true);
        }

        @Override
        public void onErrorFetchingEvents(String error) {
            assertFalse("This method shouldn't be called", true);
        }

        @Override
        public void onErrorFetchingCachedEvents(String message) {
            assertFalse("This method shouldn't be called", true);
        }
    }, false);
    ...
}
...

首先调用测试。在 GetEventsInteractor#execute 方法中,我正在这样做:

...
mRepository.getEvents(new BaseApiResponse<List<ApiEventResponse>>() {
        @Override
        public void onError(String error) {
            callback.onErrorFetchingEvents(error);
        }

        @Override
        public void onResponse(List<ApiEventResponse> apiResponse) {

            mapEventResponse(apiResponse)
                    .subscribe(new Subscriber<List<Event>>() {
                @Override
                public void onCompleted() {

                }

                @Override
                public void onError(Throwable e) {

                }

                @Override
                public void onNext(List<Event> items) {
                    mScheduleDbCache.setSchedules(mGetUserSipid.get(), items);
                    mScheduleMemoryCache.setSchedules(mGetUserSipid.get(),items);

                    callback.onEventsFetched(items);
                    onCompleted();
                }
            });
        }
        ...
}
...

我要对一个很大的列表进行排序。 mapEventResponses 方法负责对 rx.Observable 中的列表进行排序。

private Observable<List<Event>> mapEventResponse(final List<ApiEventResponse> apiResponse) {

    return Observable.create(new Observable.OnSubscribe<List<Event>>() {
        @Override
        public void call(final Subscriber<? super List<Event>> subscriber) {
            List<Event> items = new ArrayList<>();
            if (apiResponse != null) {
                for (ApiEventResponse obj : apiResponse) {
                    if (obj == null) continue;
                    items.add(EventMapper.transform(obj));
                }
            }
            Collections.sort(items, new Comparator<Event>() {
                public int compare(Event ev1, Event ev2) {
                    return ev1.getmStartTs().compareToIgnoreCase(ev2.getmStartTs());
                }
            });

            subscriber.onNext(items);
        }
    }).subscribeOn(mBackgroundScheduler).observeOn(mMainScheduler);
}

这是方法,我检查了 mBacgroundSceduler 和 mMainScheduler 是否正确注入。

这个测试用例中的每一步都执行得很完美,问题是当我到达这里的资产时:

assertTrue(false); //This asserts should throw an exception
assertEquals(42343, eventList.size());

什么都没发生,我尝试了几种调度程序的组合,但都没有奏效。关于我做错了什么的任何想法。考试 最终成功运行,但显然应该在这些断言上崩溃。

【问题讨论】:

  • 似乎您的测试方法在回调执行之前返回
  • 您在执行任务期间可能遇到错误,并且看起来您没有将错误传播到回调。我还看到您正在模拟存储库,可能它对任务没有任何作用

标签: android unit-testing rx-java


【解决方案1】:

正如@Eugen Martynov 指出的那样,问题是我在调用mapEventResponse() 方法时返回的rx.Observable 正在捕获AssertException,然后它就死了。我发现的一种解决方法是创建一个 ExceptionSubscriber 类:

public abstract class ExceptionSubscriber<T> extends rx.Subscriber<T> {

    @Override
    public void onCompleted() {

    }

    @Override
    public void onError(Throwable e) {
        throw new RuntimeException(e);
    }

    @Override
    public void onNext(T t) {

    }
}

然后由assertTrue(false); 行生成的AssertException 被正确传播和处理。

例如:

    mRepository.getEvents(new BaseApiResponse<List<ApiEventResponse>>() {
        @Override
        public void onError(String error) {
            callback.onErrorFetchingEvents(error);
        }

        @Override
        public void onResponse(List<ApiEventResponse> apiResponse) {

            mapEventResponse(apiResponse).subscribe(new ExceptionSubscriber<List<Event>>() {
                @Override
                public void onNext(List<Event> items) {
                    mScheduleDbCache.setSchedules(mGetUserSipid.get(), items);
                    mScheduleMemoryCache.setSchedules(mGetUserSipid.get(),items);

                    callback.onEventsFetched(items);
                    onCompleted();
                }
            });
        }
        ...

我愿意接受任何更好的解决方案。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-06-30
    • 1970-01-01
    • 2021-03-05
    • 2022-11-10
    • 2020-01-10
    • 2014-07-16
    • 2018-12-12
    相关资源
    最近更新 更多