I have:
val observable: Observable[Int] = Observable.from(List(5))
and I can test that the input list is indeed passed on to the observable by testing:
materializeValues(observable) should contain (5)
where materializeValues is:
def materializeValues[T](observable: Observable[T]): List[T] = {
observable.toBlocking.toIterable.toList
}
Now, if I create an observable from a future, I can't seem to use materializeValues for the test as the test times out. So if I have:
val futVal = Future.successful(5)
val observable: Observable[Int] = Observable.from(futVal)
materializeValues(observable) should contain(5)
it times out and does not pass the test. What is different in the process of materializing these two observables, which leads to me not being able to block on it?
Also, what is the idomatic way of testing an observable? Is there any way of doing it without calling toBlocking?
I think the problem is that you use
AsyncWordSpecLike(by the way whyAsyncWordSpecLikeinstead ofAsyncWordSpec?).AsyncWordSpecLike/AsyncWordSpecare designed to simplify testingFuture. UnfortunatelyObservableis a more powerful abstraction that can't be easily mapped onto aFuture.Particularly
AsyncWordSpecLike/AsyncWordSpecallow your tests to returnFuture[Assertion]. To make it possible it provides custom implicitExecutionContextthat it can force to execute everything and know when all scheduled jobs have finished. However the same customExecutionContextis the reason why your second code doesn't work: processing of the scheduled jobs starts only after execution of your test code has finished but your code blocks on thefutValbecause unlucklily for you callback registered inFuture.onCompleteis scheduled to be run on theExecutionContext. It means that you have a kind of dead-lock with your own thread.I'm not sure what is the official way to test
Observableon Scala. In Java I think TestSubscriber is the suggested tool. As I saidObservableis fundamentally more powerful thing thanFutureso I think to testObservableyou should avoid usingAsyncWordSpecLike/AsyncWordSpec. If you switch to useFlatSpecorWordSpec, you can do something like this: