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

时间:2019-06-09 16:45:31

标签: android mockito rx-java rx-java2

我的方法中有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
}

在测试方法末尾的验证中,我希望在第一个complet发出错误之后,最后3个验证应该成功运行,即永远不要调用最后3个verify()

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

如果第一个可完成的代码发出错误,是否永远不会调用andThen()

2 个答案:

答案 0 :(得分:2)

Get-ChildItem -Recurse | `
   Where-Object {$_.Name -match '&' -or $_.Name -match '%' } | `
     Rename-Item -NewName { $_.Name -replace '&','_' -replace '%','_' }
  

如果第一个可完成的代码发出错误,应该不调用andThen()吗?

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

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

completable2.doSomethingElse()

编辑:进一步说明:

鉴于您的方法定义如下:

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 将永远不会执行

答案 1 :(得分:0)

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

抽象示例:

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