I am observing a strange behavior. In on of my test cases, I am using contentAsJson
. In that test case, the compiler is not complaining that I have to provide an implicit
value for Timeout
and Materializer
class UserControllerUnitSpec extends PlaySpec with BeforeAndAfterAll with BeforeAndAfterEach with OneAppPerSuiteWithComponents{
..
"User signup request with body but with incorrect profile data " should {
"return error message " in {
...val resultFuture: Future[Result] = testEnv.controller.signupUser(request)
val responseBodyAsJsValue: JsValue = contentAsJson(resultFuture)//works
...
}
}
But in another test case, the compiler gives error that I need to provide the value
class QuestionsControllerUnitSpec extends PlaySpec with BeforeAndAfterAll with BeforeAndAfterEach with OneAppPerSuiteWithComponents{
...
"newQuestion" should {
"should return error if the size of the body in the request is more than the maximum allowed size" in {
...
val response:Accumulator[ByteString,Result] = questionController.newQuestion(request)
val responseBody = contentAsJson(response)//(Timeout(Duration(5000,"millis")),testEnv.testEnv.mat).
...
}
I get error
Error:(1485, 39) could not find implicit value for parameter mat: akka.stream.Materializer
val responseBody = contentAsJson(response)//(Timeout(Duration(5000,"millis")),testEnv.testEnv.mat)
How can I debug why one is working but the other isn't?
UPDATE - added return types after Mario's answer.
Try providing implicit Materializer
like so
import play.api.test.Helpers._
implicit val actorSystem = ActorSystem("test")
implicit val materializer = ActorMaterializer()
val responseBody = contentAsJson(response)
instead of explicit testEnv.testEnv.mat
contentAsJson(response)(Timeout(Duration(5000,"millis")),testEnv.testEnv.mat)
Regarding the difference between the two tests, note there are two overloaded versions of contentAsJson
def contentAsJson(of: Future[Result])(implicit timeout: Timeout, mat: Materializer = NoMaterializer): JsValue
def contentAsJson(of: Accumulator[ByteString, Result])(implicit timeout: Timeout, mat: Materializer): JsValue
where in the first case we see default Materializer
argument is provided
mat: Materializer = NoMaterializer
while in the second case we have to provided our own. Therefore it is likely that in the first test the type of resultFuture
is Future[Result]
whilst in the second test the return type of response
is Accumulator
.
Regarding finding out where the implicit is provided from, personally I use IntelliJ's View | Show Implicit Hints
feature.