Как проверить контроллер в приложении, использующем внедрение времени компиляции - PullRequest
0 голосов
/ 05 июня 2018

Мое приложение использует инъекцию времени компиляции.Загрузчик определяется следующим образом (фрагмент кода):

class AppLoader extends ApplicationLoader { ...}

class AppComponents (context: Context) extends BuiltInComponentsFromContext(context) {
...

//within this I have created instances of my controller and created a route
    lazy val userController = new UserController(userRepository, controllerComponents, silhouetteJWTProvider)

lazy val router = new Routes(httpErrorHandler, homeController,userWSRoutes, countController,asyncController, assets)

}

Класс UserController имеет signupUser Action

@Singleton
class UserController @Inject()(
userRepo: UsersRepository,cc: ControllerComponents, silhouette: Silhouette[JWTEnv])(implicit exec: ExecutionContext) extends AbstractController(cc){
...

def signupUser = silhouette.UserAwareAction.async{ implicit request => {
...
}
}

Я хочу проверить signupUserAction но я не знаю, как это сделать.Я создал следующий класс спецификации, но я застрял в том, как написать спецификацию и проверить ее.

class UserControllerSpec extends PlaySpec {


    "User signup request with non-JSON body" must {
      "return  400 (Bad Request) and the validation text 'Incorrect body type. Body type must be JSON'" in {

//I want to create instance of a `FakeRequest` annd pass it to UserController.signupUser. I should test a Future[Result] which I should then assert.

//How do I get instance of userController which I created in my Apploader? I don't want to repeat/duplicate the code of AppLoader here.

      }
    }
}

1 Ответ

0 голосов
/ 06 июня 2018

Существующие компоненты из ApplicationLoader могут быть непосредственно созданы в тестах .Mixin WithApplicationComponents trait и override def components: BuiltInComponents:

override def components: BuiltInComponents = new YourComponents(context)

Вот пример реализации вашего теста:

import org.scalatestplus.play._
import org.scalatestplus.play.components.OneAppPerSuiteWithComponents
import play.api.BuiltInComponents
import play.api.mvc.Result
import play.api.libs.json.Json
import play.api.test.Helpers._
import play.api.test._
import scala.concurrent.Future

class UserControllerSpec extends PlaySpec with OneAppPerSuiteWithComponents {

  override def components: BuiltInComponents = new YourComponents(context)

  "User signup request with non-JSON body" should {

    "return  400 (Bad Request) and the validation text 'Incorrect body type. Body type must be JSON'" in {

      val Some(result): Option[Future[Result]] =
        route(
          app, 
          FakeRequest(POST, "/signup").withJsonBody(Json.parse("""{"bad": "field"}"""))
        )

      status(result) mustBe BAD_REQUEST
    }
  }
}

Helpers.stubControllerComponents очень полезно для модульного тестирования контроллеров.Вот пример того, как его можно использовать для реализации того же теста, не имея дело с ApplicationLoader.

import akka.actor.ActorSystem
import akka.stream.ActorMaterializer
import controllers.UserController
import org.scalatest.mockito.MockitoSugar
import org.scalatestplus.play._
import play.api.libs.json.Json
import play.api.test.Helpers._
import play.api.test._

class UserControllerSpec extends PlaySpec with MockitoSugar {

  "User signup request with non-JSON body" should {

    "return  400 (Bad Request) and the validation text 'Incorrect body type. Body type must be JSON'" in {

      implicit val actorSystem = ActorSystem()
      implicit val materializer = ActorMaterializer()

      val controller = new UserController(
        mock[UsersRepository]
        Helpers.stubControllerComponents(playBodyParsers = Helpers.stubPlayBodyParsers(materializer)),
        mock[Silhouette[JWTEnv]]
      )

      val result = 
        call(
          controller.signupUser, 
          FakeRequest(POST, "/signup").withJsonBody(Json.parse("""{"bad": "field"}"""))
        )

      status(result) mustBe BAD_REQUEST
    }
  }
}
...