我在一种方法中有 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()
}
)