I'm having trouble unit testing a controller in Play 2.6 and would appreciate the help.
The problem is that my Controller method uses a custom Action 'languageAction' and I get a null pointer exception when I run the tests
My Controller method:
class ApplicationController @Inject()(languageAction: LanguageAction, cc: ControllerComponents)
extends AbstractController(cc)
with I18nSupport
with LazyLogging {
def error(error: String): Action[AnyContent] = languageAction {
implicit request: RequestHeader =>
BadRequest(views.html.error(error))
}
}
My custom action that looks at the query string before it is processed by the controller and adds a header to the request:
class LanguageAction @Inject() (parser: BodyParsers.Default)(implicit ec: ExecutionContext) extends ActionBuilderImpl(parser) {
override def invokeBlock[A](request: Request[A], block: (Request[A]) => Future[Result]): Future[Result] = {
val languageCode = request.getQueryString("ui_locales") match {
case Some("cy") => "cy"
case _ => "en"
}
val newRequest = request.withHeaders(Headers(("Accept-Language", languageCode)))
block(newRequest)
}
}My unit test, I am mocking 'languageAction' and I suspect Mockito doesn't mock it properly. I get a null pointer exception on line 16.
class ApplicationControllerSpec extends PlaySpec
with MockitoSugar with ScalaFutures with GuiceOneAppPerTest with Results {
implicit lazy val materializer: Materializer = app.materializer
val languageAction = mock[LanguageAction]
"error" should {
"return a 400 bad request" in {
val controller = new ApplicationController(languageAction, stubControllerComponents())
val newRequest = FakeRequest().withCSRFToken
val method = controller.error("error")(newRequest) //line 16
status(method) mustEqual 400
}
}
}
I've tried app.injecting in an instance of 'languageAction' but that didn't work.I've also tried mocking out 'languageAction.invokeBlock' as it's a future but that also didn't work. Any advice or solutions would be welcome, thanks.