I have 2 completables in a method, like:
completable1.doSomething()
.andThen(completable2.doSomethingElse())
And I want to test it, by using Mockito and returning error in the first completable. Here is my original method:
public Completable updateQuestion(Question question){
return gameRepositoryType.updateQuestion(question)
.andThen(gameRepositoryType.getGameById(question.getqId())
.map(GAME_MAPPER)
.flatMapCompletable(gameRepositoryType::updateGame))
.observeOn(AndroidSchedulers.mainThread());
}
And here is my test:
@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
}
In my verifications at the end of the test method, I am expecting after the first completable emitts an error, the 3 last verifications should run with success, i.e the 3 last verify()
should never be called.
However I can see that all methods are called even though gameRepositoryType.updateQuestion(question)
emitts error. Why is that?
Shouldn't andThen()
never be called if the first completable emitts error?
completable1.doSomething()
.andThen(completable2.doSomethingElse())
Shouldn't andThen() never be called if the first completable emitts error?
andThen
will always call completable2.doSomethingElse()
to build the stream, but the Completable that is returned by it will never be subscribed to.
You can test it this way:
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();
Edit: for further clarification:
Given your methods are defined like this:
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();
});
}
Suppose you call:
updateQuestion(question)
.andThen(updateGame())
.subscribe();
And database.updateQuestion(question);
throws an error.
Then your log output would be:
prints when the updateQuestion is called
prints when the updateGame is called
prints when updateQuestion is subscribed to
>> error
and database.updateGame();
will never be executed
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With