Non-blocking external calls (web service) calls often would return a Future
which will resolve to some value in the future. Testing such values in Java
is pretty sad. Testing futures in java
will usually involve performing a get()
to resolve a future and then perform the assertions. I am pretty new to scala
and was curious if I would have to do the same. Fortunately with Scala
this is not the case. I will walk you thru my experience with an example and lets see how we do it in scala
. In this post, we will be using scala-test
library as our testing library and use FlatSpec
type of testing.
Let’s start by defining our class to test.
The above code is a simple scala
class that will simulate a dummy network call by just sleeping for an arbitrary amount time.
lengthOfTheResponse(url: String): Future[Int]
is a function that waits for 5 seconds and returns the number 10.
Similarly, statusOfSomeOtherResponse(url: String): Future[Int]
is another function that waits for 1 second and returns the number 200. Let’s see how we write tests for these function.
The above example looks great but will fail with the following error.
A timeout occurred waiting for a future to complete. Queried 10 times, sleeping 15 milliseconds between each query.
The default behavior of whenReady
is to keep polling 10 times by waiting for 15 milliseconds in between to see if the future is resolved. If not, we get the above error. This clearly is not a consistent solution as we are depending on a finite time and polling to figure out the future result. Sure, we can configure the above whenReady
method with a higher timeout and retry but there are better ways to test. Let’s see another approach.
The above example will first execute the lengthOfTheResponse("testurl")
resolve the future and yield
the result Int
into res
variable. We then assert
the result. But there is a gotcha we need to keep in mind. It is important that we use the AsyncFlatSpec
instead of FlatSpec
.
We can also do more fluent version with multiple network calls.
This way, we can kind of chain the futures in the order that we want to test and perform assertions
accordingly. This will ensure that the futures resolve appropriately.
Let me know what you think of this and would certainly like to learn other approach to test futures.