问题
This is a continuation of a prior question in which answer I saw that I had a misconception about the use of plugins in FakeApplication.
First I have a Model created as a trait and a object that implment it.
trait UserModel extends ModelCompanion[User, ObjectId] {
// ...
}
object User extends UserModel
Next, I have a Controller, created as a abstract class that receive a instance of UserModel, and its respective implementation that uses the User object.
abstract class UsersController extends Controller {
val userModel: UserModel
def sayHello = Action(parse.json) { request =>
// return a play Action. It doesn't use userModel
}
// Other methods
}
object Users extends UsersController(User)
In test directory, I created a UsersController Stub using a UserModel mock:
package controllers
import org.specs2.mock.Mockito
object UserControllersTest extends UsersController with Mockito {
val userModel = mock[models.UserModel]
}
Now I have my UsersControllers Spec test:
package controllers
import org.specs2.mutable.Specification
import play.api.libs.json.Json
import play.api.test._
import play.api.test.Helpers._
class UsersSayHelloSpec extends Specification {
running(FakeApplication()) {
"Users.SayHello" should {
def sendJson(jsonMap: Map[String, String], shouldBeCorrect: Boolean) = {
running(new FakeApplication(
additionalPlugins = Seq("controllers.UserControllersTest"))) {
// Preapration
val jsonRequisition = Json.toJson(jsonMap)
// ***************************************
// It will call UsersControllers.sayHello
val Some(result) = routeAndCall(FakeRequest(POST,
"/hello",
FakeHeaders(Map("Content-Type" -> Seq("application/json"))),
jsonRequisition))
// ***************************************
// ...
}
}
"Not process a empty String" in {
sendJson(Map.empty[String, String], false)
}
// Other tests calling sendJson ...
}
}
}
So my question is: How can I say to FakeApplication to use UserControllersTest instead the real UserControllers implementation when call "/hello" URL, in routeAndCall() calling?
回答1:
There are two different part of your application which you might want to test:
- The controller itself
- The http router
When you test the controller itself, you typically create a request and you directly pass it to a controller method, which will generate the answer. You then perform some validation of the answer to verify the test result.
When you test the router, what you want to test is that the request is routed to the right controller method: you directly call the url and you check that the result is the one you expect from the controller you expected.
What you are trying to do does not make much sense to me:
if on route /hello I have a dummyController, will my post to the route /hello works correctly?
Since the routes file is compiled into a Scala class which actually works as a router, if (and I am not sure) such a dynamic routing feature is available in play, you would have to:
- Delete the existing route on the /hello path
- Add a new route point to a different controller
来源:https://stackoverflow.com/questions/13302657/play-2-0-fakeapplication-calling-a-stub-controller-instead-real-one