NullPointerException при тестировании контроллера в Play 2.6 - PullRequest
0 голосов
/ 22 мая 2018

Я работаю над приложением Scala Play 2.6, которое использует ReactiveMongo.Я последовал примеру HomeControllerSpec.scala установки Play 2.6 по умолчанию (play-scala-seed.g8), чтобы протестировать мой ProjectController, создав новый его экземпляр, но я получаю NullPointerException.

Вот мой контроллер:

class ProjectController @Inject()(
      cc: ControllerComponents,
      val reactiveMongoApi: ReactiveMongoApi
  )(implicit ec: ExecutionContext) extends AbstractController(cc) with I18nSupport {

  def collection: Future[JSONCollection] = reactiveMongoApi.database.map(
    _.collection[JSONCollection]("project")
  )

  def listProjects: Action[AnyContent] = Action.async { implicit request =>
    val futureProjectsList: Future[List[Project]] = collection.flatMap(
      _.find(Json.obj())
      .projection(Json.obj())
      .cursor[Project]()
      .collect[List](-1, Cursor.FailOnError[List[Project]]())
    )

    for {
      projectsList <- futureProjectsList
    } yield {
      Ok(views.html.project.list(projectsList))
    }
  }
}

И это мой тест:

class ProjectControllerSpec extends PlaySpec
  with GuiceOneAppPerTest
  with Injecting
  with MockitoSugar {

  val mockedReactiveMongoApi: ReactiveMongoApi = mock[ReactiveMongoApi]
  val mockedExecutionContext: ExecutionContext = mock[ExecutionContext]

  "ProjectController GET" should {
    "render the 'List of Projects' page from a new instance of controller" in {
      val controller: ProjectController = new ProjectController(
                                                      stubControllerComponents(),
                                                      mockedReactiveMongoApi
                                                    )(mockedExecutionContext) {
        override def collection: Future[JSONCollection] = mock[Future[JSONCollection]]
      }
      val result = controller.listProjects().apply(FakeRequest(GET, "/projects"))

      status(result) mustBe OK
      contentType(result) mustBe Some("text/html")
      contentAsString(result) must include ("Projects")
    }
  }
}

Но когда я запускаю тест, я получаю:

[info]   java.lang.NullPointerException:
[info]   at controllers.ProjectController.$anonfun$listOfProjects$1(ProjectController.scala:51)
[info]   at play.api.mvc.ActionBuilderImpl.invokeBlock(Action.scala:482)
[info]   at play.api.mvc.ActionBuilderImpl.invokeBlock(Action.scala:480)
[info]   at play.api.mvc.ActionBuilder$$anon$2.apply(Action.scala:419)
[info]   at controllers.ProjectControllerSpec.$anonfun$new$2(ProjectControllerSpec.scala:40)
[info]   at org.scalatest.OutcomeOf.outcomeOf(OutcomeOf.scala:85)
[info]   at org.scalatest.OutcomeOf.outcomeOf$(OutcomeOf.scala:83)
[info]   at org.scalatest.OutcomeOf$.outcomeOf(OutcomeOf.scala:104)
[info]   at org.scalatest.Transformer.apply(Transformer.scala:22)
[info]   at org.scalatest.Transformer.apply(Transformer.scala:20)

Я также запустил 2 других теста для этих контроллеров, и они прошли (рендеринг страницы из приложения путем введения контроллера, рендеринга с маршрутизатора).Итак, как мне пройти этот тест?Заранее благодарю за помощь.

1 Ответ

0 голосов
/ 23 мая 2018

NullPointerException происходит от использования фиктивных объектов, которые не имеют определенного поведения.Поэтому, когда выполнение достигнет reactiveMongoApi.database, это вызовет исключение.

Этот проект github представил способ насмешки над реактивным Mongo API, но он больше не поддерживается.

Вы также можете проверить помощник , который позволяет смоделировать соединение монго.

Кстати, вы не должны использовать насмешки для ExecutionContext, иначе ваши Future s выиграют 'т работа

...