【发布时间】:2015-07-03 05:13:38
【问题描述】:
我对 Play2 和 Scala 还是很陌生。我正在编写一个使用 ReactiveMongo 插件的简单应用程序。
我写了一个简单的对象用作 DAO
object UserDAO {
def db: reactivemongo.api.DB = ReactiveMongoPlugin.db
def collection: JSONCollection = db.collection[JSONCollection]("users")
collection.indexesManager.ensure(Index(List("name" -> IndexType.Ascending),
unique = true))
def insert(User): Future[LastError] = {
collection.insert(unit)
}
def findOne(query: JsObject): Future[Option[User]] = {
collection.find(query).one[User]
}
def removeOne(query: JsObject): Future[LastError] = {
collection.remove(query, firstMatchOnly = true)
}
...
}
注意,我创建一个索引是为了确保不能创建两个同名的用户。 通过这种方式,我可以在我的控制器中使用 DAO,如下所示
class Users extends Controller with MongoController {
def createUser = Action.async(parse.json) {
request =>
request.body.validate[User].map {
user =>
UserDAO.insert(user).map {
lastError =>
Created(s"User Created")
}
}.getOrElse(Future.successful(BadRequest("invalid json")))
}
}
到目前为止一切顺利。 问题来自规格测试。我有两个测试套件,我将它们配置为在不同的数据库上工作。 第一个测试套件使用数据库“mydb1”:
val addConf = Map("mongodb.uri" -> ("mongodb://localhost:27017/mydb1"))
class UsersTest1 extends PlaySpecification {
sequential
"Users" should {
"create a User" in new WithApplication(FakeApplication(
additionalConfiguration = addConf)) {
val request = FakeRequest(POST, "/user")
.withJsonBody(Json.obj(
"name" -> "foo",
"age" -> 3))
val response = route(request)
...
...
}
}
}
第二个测试套件使用数据库“mydb2”
val addConf = Map("mongodb.uri" -> ("mongodb://localhost:27017/mydb2"))
class UsersTest2 extends PlaySpecification {
sequential
"Users" should {
"create a User" in new WithApplication(FakeApplication(
additionalConfiguration = addConf)) {
val request = FakeRequest(POST, "/user")
.withJsonBody(Json.obj(
"name" -> "foo",
"age" -> 3))
val response = route(request)
...
...
}
}
}
问题是,在完整的测试运行之后,使用 mongo CLI 我看到只有在两个生成的数据库之一中实际存在索引。
看起来 UserDAO 单例对象实例在所有 FakeApplications 之间共享,因此在第一次访问对象时,对于所有测试只执行一次对 collection.indexesManager.ensure(...) 的调用.
作为证明,我尝试将 collection.indexesManager.ensure(...) 调用移到 UserDAO.insert() 函数中,实际上它解决了问题。
我曾经认为 FakeApplications 是应用程序的完全孤立的实例。
【问题讨论】:
标签: scala playframework-2.0 specs2 reactivemongo