Play 2.0: FakeApplication calling a stub controller instead real one

不羁岁月 提交于 2019-12-13 02:13:15

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!