Search code examples
scalaintellij-ideaplayframeworkspecs2

How to combine WithApplication(Loader) and ExecutionEnv


I am writing Specs2 tests for methods returning futures in a project using Scala and Play framework. Documentation and answers to this question recommend using the await modifier, which requires to add implicit ExecutionEnv. A minimal working example (adapted from one of the mentioned answers):

class FutureSpec extends mutable.Specification {
  "Even in future one" should {
    "be greater than zero" in { implicit ee: ExecutionEnv =>
      Future(1) must be_>(0).await
    }
  }
}

But some of my tests require WithApplicationLoader. If I add it to the example, it does not compile:

class FutureSpec extends mutable.Specification {
  "Even in future one" should {
    "be greater than zero" in new WithApplicationLoader { implicit ee: ExecutionEnv =>
      Future(1) must be_>(0).await
    }
  }
}

WithApplication instead of WithApplicationLoader has exactly the same effect (expectedly).

Is it possible to use WithApplicationLoader together with implicit ExecutionEnv?

Unfortunately, the second option described in the documentation -- moving ExecutionEnv to the class constructor instead of a particular method -- is not available. This specification:

class FutureSpec(implicit ee: ExecutionEnv) extends mutable.Specification {
  "Even in future one" should {
    "be greater than zero" in new WithApplicationLoader {
      Future(1) must be_>(0).await
    }
  }
}

works, but it is ignored by IntelliJ Idea (I can run such a specification separately, but the configuration running all tests in the project does not execute it).


Solution

  • This works for me with IntelliJ 2016.1.3:

    import play.api.test.{PlaySpecification, WithApplication}
    import org.specs2.concurrent.ExecutionEnv
    import scala.concurrent.Future
    
    class FutureSpec extends PlaySpecification {
      implicit val ee = ExecutionEnv.fromGlobalExecutionContext
    //  // or this:
    //  implicit val ee = ExecutionEnv.fromExecutionContext(play.api.libs.concurrent.Execution.Implicits.defaultContext)
    
      "Even in future one" should {
        "be greater than zero" in new WithApplication {
          Future(1) must be_>(0).await
        }
      }
    }
    

    Here is my build.sbt:

    name := "throwaway"
    
    version := "1.0"
    
    scalaVersion := "2.11.8"
    
    libraryDependencies += "org.specs2" %% "specs2-core" % "3.8.5.1" % "test"
    
    libraryDependencies += "com.typesafe.play" %% "play" % "2.5.9" % "test"
    
    libraryDependencies += "com.typesafe.play" %% "play-specs2" % "2.5.9" % "test"
    
    libraryDependencies += "com.typesafe.play" %% "play-test" % "2.5.9" % "test"