I have developed RESTful services using play 2.5 and I am trying to develop functional tests for my services. I am following the official documentation here todo it.
Here is the test for the controller:
package com.x.oms.controller
import org.scalatestplus.play._
import play.api.inject.guice.GuiceApplicationBuilder
import play.api.mvc.Action
import play.api.mvc.Results._
import play.api.routing.Router
import play.api.test.Helpers.{GET => GET_REQUEST}
class Test extends PlaySpec with OneServerPerSuite {
implicit override lazy val app =
new GuiceApplicationBuilder().router(Router.from {
// TODO: Find out how to load routes from routes file.
case _ => Action {
Ok("ok")
}
}).build()
"Application" should {
"be reachable" in {
// TODO: Invoke REST services using Play WS
// TODO: Assert the result
}
}
}
Here is the the controller:
package controllers.com.x.oms
import com.google.inject.Inject
import com.x.oms.AuthenticationService
import com.x.oms.model.DBModels.User
import com.x.oms.model.UIModels.Token
import play.api.Logger
import play.api.libs.json.Json
import play.api.mvc.{Action, Controller}
class AuthenticationController @Inject()(as: AuthenticationService) extends Controller {
private val log = Logger(getClass)
def authenticate = Action(parse.json) {
request =>
val body = request.body
val username = (body \ "username").as[String]
val password = (body \ "password").as[String]
log.info(s"Attempting to authenticate user $username")
val token = as.authenticate(User(username, password))
log.debug(s"Token $token generated successfully")
token match {
case token: String => Ok(Json.toJson(new Token(token)))
case _ => Unauthorized
}
}
def logout = Action {
request =>
val header = request.headers
as.logout(header.get("token").get)
Ok("Logout successful")
}
def index = Action {
request =>
Ok("Test Reply")
}
}
Routes file:
# Routes
# This file defines all application routes (Higher priority routes first)
# ~~~~
POST /login controllers.com.x.oms.AuthenticationController.authenticate
POST /logout controllers.com.x.oms.AuthenticationController.logout
GET / controllers.com.x.oms.AuthenticationController.index
I do not want to redefine the routes info in each test. I need your help to load the routes file while building the app in each test.
Please let me know how the route file can be loaded. Thanks in advance.
I would suggest that you test your AuthenticationService
outside of the Play infrastructure. If you looking to test the controllers themselves, they're just classes you can new up and call directly using a FakeRequest
:
val api = new AuthenticationController(as)
"fail an authentication attempt with bad credentials" in {
val request = FakeRequest(POST, "/login")
.withJsonBody(jsonBadCredentials)
val result = call(api.authenticate(), request)
status(result) mustBe UNAUTHORIZED
}