rxjava 单元测试 onError 未调用

eri*_*icn 1 junit android mockito rx-java

onCompleted被称为,所以很奇怪

方法:

void load() {
    fetchData().subscribeOn(getIoScheduler())
            .observeOn(getMainThreadScheduler())
            .doOnError(throwable -> System.out.println("doOnError " + throwable))
            .subscribe(new Subscriber<MyObject>() {
                @Override
                public void onCompleted() {
                    System.out.println("onCompleted");
                }

                @Override
                public void onError(Throwable e) {
                    System.out.println("onError " + e);
                    handleError();
                }

                @Override
                public void onNext(MyObject myObject) {
                    handleSuccess(myObject);
                }
            });
 }
Run Code Online (Sandbox Code Playgroud)

考试:

@Test
public void load() {
        Mockito.doReturn(Schedulers.immediate())
                .when(presenter)
                .getMainThreadScheduler();
        Mockito.doReturn(Schedulers.immediate())
                .when(presenter)
                .getIoScheduler();

        // a) Success case
MyObject object = Mockito.mock(MyObject.class);
        Mockito.doReturn(Observable.just(object))
                .when(presenter)
                .fetchData();

        presenter.load();

        Mockito.verify(presenter)
                .fetchData();
        Mockito.verify(presenter)
                .handleSuccess(object);
        Mockito.reset(presenter);

        // b) Error case
        Mockito.doReturn(Observable.error(new Exception("dummy exception"))).when(presenter)
                .fetchData();

        presenter.load();

        Mockito.verify(presenter)
                .handleError();
}
Run Code Online (Sandbox Code Playgroud)

在控制台中,仅onCompleted打印出来。

有趣的是,当我删除测试成功场景的代码时,它按预期工作:

@Test
    public void load() {
            Mockito.doReturn(Schedulers.immediate())
                    .when(presenter)
                    .getMainThreadScheduler();
            Mockito.doReturn(Schedulers.immediate())
                    .when(presenter)
                    .getIoScheduler();

            // b) Error case
            Mockito.doReturn(Observable.error(new Exception("dummy exception"))).when(presenter)
                    .fetchData();

            presenter.load();

            Mockito.verify(presenter)
                    .handleError();
    }
Run Code Online (Sandbox Code Playgroud)

输出:

onError
Run Code Online (Sandbox Code Playgroud)

我在这里缺少什么?在测试错误场景之前我是否应该重置某些内容?

我正在使用 RxJava 1.3.4

R. *_*ski 5

也许这里的关键是:

Mockito.reset(presenter);
Run Code Online (Sandbox Code Playgroud)

调用该方法会删除与线程相关的任何模拟,因为它仅在测试方法开始时设置一次,并且重置后不会再次设置模拟 thead。

老实说,测试成功和错误测试用例应该是两个不同的测试场景,这将允许省略重置模拟。

第一个场景:

@Test
public void loadSuccess() {
    Mockito.doReturn(Schedulers.immediate())
            .when(presenter)
            .getMainThreadScheduler();
    Mockito.doReturn(Schedulers.immediate())
            .when(presenter)
            .getIoScheduler();
    MyObject object = Mockito.mock(MyObject.class);
    Mockito.doReturn(Observable.just(object))
            .when(presenter)
            .fetchData();

    presenter.load();

    Mockito.verify(presenter)
            .fetchData();
    Mockito.verify(presenter)
            .handleSuccess(object);
}
Run Code Online (Sandbox Code Playgroud)

第二种(错误)场景:

@Test
public void loadError() {
    Mockito.doReturn(Schedulers.immediate())
            .when(presenter)
            .getMainThreadScheduler();
    Mockito.doReturn(Schedulers.immediate())
            .when(presenter)
            .getIoScheduler();
    Mockito.doReturn(Observable.error(new Exception("dummy exception"))).when(presenter)
            .fetchData();

    presenter.load();

    Mockito.verify(presenter)
            .handleError();
}
Run Code Online (Sandbox Code Playgroud)