RxJava2: .andThen() 调用,即使第一个 Completable 发出错误



我在一种方法中有 2 个可编译对象,例如:

completable1.doSomething()
    .andThen(completable2.doSomethingElse())

我想通过使用 Mockito 并在第一个完成项中返回错误来测试它。这是我的原始方法:

 public Completable updateQuestion(Question question){
    return gameRepositoryType.updateQuestion(question)
            .andThen(gameRepositoryType.getGameById(question.getqId())
                    .map(GAME_MAPPER)
                    .flatMapCompletable(gameRepositoryType::updateGame))
            .observeOn(AndroidSchedulers.mainThread());
}

这是我的测试:

@Test
public void updateQuestionError(){
    when(gameRepositoryType.updateQuestion(question)).thenReturn(Completable.error(error));
    when(question.getqId()).thenReturn(FAKE_QID);
    when(gameRepositoryType.getGameById(FAKE_QID)).thenReturn(Single.just(game));
    when(gameRepositoryType.updateGame(game)).thenReturn(Completable.complete());
    interactor.updateQuestion(question)
            .test()
            .assertNotComplete()
            .assertError(error);
    verify(gameRepositoryType).updateQuestion(question);       //this is called in test
    verify(question,never()).getqId();                         //this is called in test
    verify(gameRepositoryType,never()).getGameById(FAKE_QID);  //this is called in test
    verify(gameRepositoryType,never()).updateGame(game);       //this is NEVER called in test
}

在测试方法结束时的验证中,我预计在第一个可完成的发射错误之后,最后 3 个验证应该成功运行,即永远不应该调用最后 3 个verify()

但是,我可以看到即使发出错误gameRepositoryType.updateQuestion(question)也会调用所有方法。为什么?

如果第一个可完成的发射器出错,不应该andThen()永远不会被调用吗?

completable1.doSomething()
    .andThen(completable2.doSomethingElse())

如果第一个可完成的发射器错误,不应该永远不调用 andThen(( 吗?

andThen将始终调用completable2.doSomethingElse()来构建流,但它返回的 Completable 将永远不会被订阅。

您可以通过以下方式进行测试:

when(completable1.doSomething()).thenReturn(Completable.error(error));
CompletableSubject completableSubject = CompletableSubject.create();
when(completable2.doSomethingElse()).thenReturn(completableSubject);

TestObserver testObserver = completable1.doSomething()
    .andThen(completable2.doSomethingElse()).test();
// Verify that completable2.doSomethingElse() was never subscribed to:
assertFalse(completableSubject.hasObservers());
testObserver
    .assertError(error)
    .assertNotComplete();

编辑:为了进一步澄清:

鉴于您的方法定义如下:

private Completable updateQuestion(Question question) {
    System.out.println("prints when the updateQuestion is called");
    return Completable.fromAction(() -> {
        System.out.println("prints when updateQuestion is subscribed to");
        database.updateQuestion(question);
    });
}
private Completable updateGame() {
    System.out.println("prints when the updateGame is called");
    return Completable.fromAction(() -> {
        System.out.println("prints when updateGame is subscribed to");
        database.updateGame();
    });
}

假设您调用:

updateQuestion(question)
    .andThen(updateGame())
    .subscribe();

database.updateQuestion(question);抛出错误。

然后,您的日志输出将是:

prints when the updateQuestion is called
prints when the updateGame is called
prints when updateQuestion is subscribed to
>> error 

database.updateGame();永远不会被处决

如果有人遇到同样的问题,请尝试defer第二个Completable。

抽象示例:

repo.executeCompletable1()
                .andThen(
                    Completable.defer {
                        repo.executeCompletable2()
                    }
                )

相关内容

  • 没有找到相关文章

最新更新