Написание ScalaTest для ReactiveMongoApi в Playframework 2.4?

Я пытаюсь начать писать тест для mongodb в своем игровом приложении.

Кажется, я не могу заставить его работать, потому что соединение отключается до выполнения сохранения.

Вот результаты

[info] UserDaoMongoSpec:
[info] UserDao
[info] - application - ReactiveMongoApi starting...
[info] - application - ReactiveMongoApi successfully started with DB 'test'! Servers:
            [localhost:27017]
[info] - should save users and find them by userId
[info] - application - ReactiveMongoApi stopping...
[info] - application - ReactiveMongoApi connections stopped. [Success(Closed)]
[INFO] [12/24/2015 15:36:43.961] [reactivemongo-akka.actor.default-dispatcher-4] [akka://reactivemongo/user/Monitor-3] Message [reactivemongo.core.actors.Close$] from Actor[akka://reactivemongo/deadLetters] to Actor[akka://reactivemongo/user/Monitor-3#1192398481] was not delivered. [1] dead letters encountered. This logging can be turned off or adjusted with configuration settings 'akka.log-dead-letters' and 'akka.log-dead-letters-during-shutdown'.
[info] ScalaTest
[info] Run completed in 3 seconds, 989 milliseconds.
[info] Total number of tests run: 1
[info] Suites: completed 1, aborted 0
[info] Tests: succeeded 1, failed 0, canceled 0, ignored 0, pending 0
[info] All tests passed.
[info] Passed: Total 1, Failed 0, Errors 0, Passed 1

Это код теста, который ничего не тестирует, но я пытаюсь сначала написать базу данных.

package test.daos

import scala.concurrent.ExecutionContext.Implicits.global

import daos.impl.UserDaoMongo

import org.scalatest._
import play.api.test._
import play.api.test.Helpers._
import org.scalatestplus.play._

class UserDaoMongoSpec extends DaosApplicationSpecOneAppPerTest {

  "UserDao" should {
    "save users and find them by userId" in {
      val userDao = new UserDaoMongo
      val future = for {
        _ <- userDao.save(credentialsTestUser)
        maybeUser <- userDao.find(credentialsTestUser.id)
      } yield maybeUser.map(_ == credentialsTestUser)
    }
  }

}

И реализация дао

package daos.impl

import java.util.UUID

import scala.concurrent.Future

import play.api.Play.current
import play.api.libs.concurrent.Execution.Implicits.defaultContext
import play.api.libs.json.Json

import play.modules.reactivemongo.ReactiveMongoApi
import play.modules.reactivemongo.json._
import play.modules.reactivemongo.json.collection.JSONCollection

import com.mohiva.play.silhouette.api.LoginInfo

import models.{User, Profile}
import models.User._

import daos.api.UserDao

import play.api.Logger

class UserDaoMongo extends UserDao {
  lazy val reactiveMongoApi = current.injector.instanceOf[ReactiveMongoApi]
  val users = reactiveMongoApi.db.collection[JSONCollection]("users")

  def find(loginInfo:LoginInfo):Future[Option[User]] =
    users.find(Json.obj("profiles.loginInfo" -> loginInfo)).one[User]

  def find(userId:UUID):Future[Option[User]] ={
    Logger.debug("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA")
    users.find(Json.obj("id" -> userId)).one[User]
  }

  def save(user:User):Future[User] =
    users.insert(user).map(_ => user)

  def confirm(loginInfo:LoginInfo):Future[User] = for {
    _ <- users.update(Json.obj(
      "profiles.loginInfo" -> loginInfo
    ), Json.obj("$set" -> Json.obj("profiles.$.confirmed" -> true)))
    user <- find(loginInfo)
  } yield user.get

  def link(user:User, profile:Profile) = for {
    _ <- users.update(Json.obj(
      "id" -> user.id
    ), Json.obj("$push" -> Json.obj("profiles" -> profile)))
    user <- find(user.id)
  } yield user.get

  def update(profile:Profile) = for {
    _ <- users.update(Json.obj(
      "profiles.loginInfo" -> profile.loginInfo
    ), Json.obj("$set" -> Json.obj("profiles.$" -> profile)))
    user <- find(profile.loginInfo)
  } yield user.get
}

Что может быть, что я делаю неправильно?

Спасибо


person agusgambina    schedule 24.12.2015    source источник
comment
Вам нужно указать, какой код вызывает проблему.   -  person cchantep    schedule 25.12.2015
comment
Спасибо @cchantep за быстрый ответ.   -  person agusgambina    schedule 25.12.2015
comment
Вы не ждете Future, которые могут (кажется) завершиться после выполнения тестов. Либо вы используете какую-то специальную функцию scalatest, чтобы заставить тесты ждать завершения фьючерсов, либо вы Await.result сами.   -  person cchantep    schedule 25.12.2015
comment
@cchantep спасибо. Оказалось, что ты был прав. Я заставляю это работать с Await.result. пожалуйста, напишите как ответ, и я отмечу как правильный ответ.   -  person agusgambina    schedule 25.12.2015
comment
Кстати, он также работал со специальной функцией scalatest, когда готов, но мне пришлось изменить настройки тайм-аута по умолчанию.   -  person agusgambina    schedule 25.12.2015


Ответы (1)


Как говорится в комментариях, получается, что ошибка была в том, что я не дождался будущего завершения. Я решил использовать специальную функцию ScalaTest, чтобы тесты ждали завершения фьючерсов.

Вот код

"UserDao" should {

  "save users and find them by userId" in withUserDao { userDao =>
    val future = for {
      user <- userDao.save(credentialsTestUser)
      maybeUser <- userDao.find(credentialsTestUser.id)
    } yield {
      maybeUser.map(_ == credentialsTestUser)
    }
    whenReady (future) { result =>
      result.get must be (true)
    }
  }
}

и на всякий случай я переопределяю поведение по умолчанию, потому что времени по умолчанию было недостаточно

implicit override val patienceConfig =
  PatienceConfig(timeout = Span(2, Seconds), interval = Span(5, Millis))

Спасибо

person agusgambina    schedule 27.12.2015