Search code examples
scalaspecs2

How to test methods that return Future?


I'd like to test a method that returns a Future. My attempts were as follows:

import  org.specs2.mutable.Specification
import scala.concurrent.ExecutionContext.Implicits.global
import scala.util.{Failure, Success}

class AsyncWebClientSpec extends Specification{

  "WebClient when downloading images" should {
    "for a valid link return non-zero content " in {
      val testImage = AsyncWebClient.get("https://www.google.cz/images/srpr/logo11ww.png")
      testImage.onComplete { res => 
        res match {
          case Success(image) => image must not have length(0)
          case _ =>
        }
        AsyncWebClient.shutDown
      }
    }
  }
}

Apart from the fact that I am unable to make this code work I guess that there could be a better way of testing a futures with a Future-oriented matcher.

How to do it properly in specs2?


Solution

  • You can use the Matcher.await method to transform a Matcher[T] into a Matcher[Future[T]]:

    val testImage: Future[String] =
       AsyncWebClient.get("https://www.google.cz/images/srpr/logo11ww.png")  
    
    // you must specify size[String] here to help type inference
    testImage must not have size[String](0).await
    
    // you can also specify a number of retries and duration between retries
    testImage must not have size[String](0).await(retries = 2, timeout = 2.seconds)
    
    // you might also want to check exceptions in case of a failure
    testImage must throwAn[Exception].await