gpt4 book ai didi

scala - Play2 Framework/Scala/Specs2 - 不同的 FakeApplications 是否共享 Singleton 对象?

转载 作者:行者123 更新时间:2023-12-03 04:11:33 26 4
gpt4 key购买 nike

我对 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)
}

...
}

请注意,我创建索引是为了确保不能创建两个同名的用户。这样我就可以在 Controller 中使用 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 是应用程序的完全隔离的实例。

最佳答案

不幸的是,是的。这使得编写并行测试非常困难(甚至不可能)。这将在 Play 2.4 中改变:https://www.playframework.com/documentation/2.4.x/ScalaDependencyInjection

关于scala - Play2 Framework/Scala/Specs2 - 不同的 FakeApplications 是否共享 Singleton 对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29850198/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com