I am trying to upgrade a Scala/Play application to Play 2.7
, Scala 2.12.11
.
I have the following test that probably used to work before I upgraded Play and Scala.
After the upgrade, I got the following compilation error:
Error: could not find implicit value for evidence parameter of type org.specs2.specification.core.AsExecution[org.specs2.concurrent.ExecutionEnv => org.specs2.matcher.MatchResult[scala.concurrent.Future[services.AuthenticationResult]]]
import org.specs2.concurrent.ExecutionEnv
import org.specs2.mutable.Specification
import scala.concurrent.duration._
class AuthenticationServiceSpec extends Specification {
"The AuthenticationService" should {
val service: AuthenticationService = new MyAuthenticationService
"correctly authenticate Me" in { implicit ee: ExecutionEnv =>
service.authenticateUser("myname", "mypassowrd") must beEqualTo (AuthenticationSuccessful).await(1, 200.millis)
}
}
}
To try to solve the compilation error, I added an implicit parameter to the class constructor (BTW, how did it work before, without an implicit parameter?):
import org.specs2.concurrent.ExecutionEnv
import org.specs2.mutable.Specification
import scala.concurrent.duration._
import scala.concurrent.Future
import org.specs2.specification.core.AsExecution
import org.specs2.matcher.MatchResult
class AuthenticationServiceSpec(implicit ee: AsExecution[ExecutionEnv => MatchResult[Future[AuthenticationResult]]]) extends Specification {
"The AuthenticationService" should {
val service: AuthenticationService = new MyAuthenticationService
"correctly authenticate Me" in { implicit ee: ExecutionEnv =>
service.authenticateUser("myname", "mypassowrd") must beEqualTo (AuthenticationSuccessful).await(1, 200.millis)
}
}
}
However in runtime when I run the test, I am getting the error:
Can't find a suitable constructor with 0 or 1 parameter for class org.specs2.specification.core.AsExecution
Based on the constructor of AsExecution
, it makes sense...
How can I solve this problem then?
This should work
class AuthenticationServiceSpec(implicit ee: ExecutionEnv) extends Specification {
"The AuthenticationService" should {
val service: AuthenticationService = new MyAuthenticationService
"correctly authenticate Me" in {
service.authenticateUser("myname", "mypassword") must beEqualTo (AuthenticationSuccessful).await(1, 200.millis)
}
}
}
The ee: ExecutionEnv
will be injected directly in the specification when it is built.
That's the meaning of the message Can't find a suitable constructor with 0 or 1 parameter for class ...
. specs2
tries to recursively build arguments for a specification if they have a constructor with 0 or 1 argument. The ExecutionEnv
is such an argument that specs2
is able to build on its own.