gpt4 book ai didi

scala - 如何使用 Slick 3 + Specs2 回滚集成测试?

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

我想为运行流畅的服务编写一些集成测试,然后通过回滚事务清理 postgresql 数据库,但我看不到这样做的方法。我知道我可以测试已经组合在一起的 DBIO 对象并将它们回滚,但是如果我想在更高的抽象级别进行测试,这似乎是不可能的。

在伪代码中,我想这样做:

StartDbTransaction() // setup
DoSomethingInDB()
AssertSomething()
RollBackDbTransaction() // teardown

例如,如果我有这个(从 play-silhouette-slick-seed 简化):

class PasswordInfoDAO(db: JdbcBackend#DatabaseDef) {

// ...
def remove(loginInfo: LoginInfo): Future[Unit] =
db.run(passwordInfoSubQuery(loginInfo).delete).map(_ => ())

}

我想我可以按照 Specs2 Guide 的方式编写一个 ForEach 特征。 ,这给出了一个通用示例:

// a transaction with the database
trait Transaction

trait DatabaseContext extends ForEach[Transaction] {
// you need to define the "foreach" method
def foreach[R: AsResult](f: Transaction => R): Result = {
val transaction = openDatabaseTransaction
try AsResult(f(transaction))
finally closeDatabaseTransaction(transaction)
}

// create and close a transaction
def openDatabaseTransaction: Transaction = ???

def closeDatabaseTransaction(t: Transaction) = ???
}

class FixtureSpecification extends mutable.Specification with DatabaseContext {
"example 1" >> { t: Transaction =>
println("use the transaction")
ok
}
"example 2" >> { t: Transaction =>
println("use it here as well")
ok
}
}

所以对于光滑,我尝试了这个:

override def foreach[R: AsResult](f: JdbcBackend#DatabaseDef => R): Result = {

val db = dbConfig.db
val session = db.createSession()
session.conn.setAutoCommit(false)
val result = AsResult(f(db))
session.conn.rollback()
result

}

然后我打算像这样使用它:

class PasswordInfoDAOSpec(implicit ee: ExecutionEnv)
extends Specification with DatabaseContext {

"password" should {
"be removed from db" in { db =>

// arrange
db.run(...) // something to set up the database

// act
PasswordInfoDAO(db).remove(loginInfo).await

// assert
PasswordInfoDAO(db).find(loginInfo) must be None.await
}
}
}

问题是 slick 3 将忽略我的 session (按设计),而是使用 session 池,所以我的回滚不会做任何事情。我认为 Slick 期望您应该在 DBIOActions 级别使用它,这些 DBIOActions 可以组合在一起并可能在不同的上下文中执行。 Slick 2 可以通过 .withSession 控制 session 。 ,但已被删除。

是每次测试都创建、迁移和删除测试数据库的唯一选择吗?

最佳答案

在谷歌搜索如何在 Slick 中回滚后,我来到了这个页面,最终发现 Slick 3 提供了对底层 JDBC 连接的访问​​,允许它在不需要 DBIO 失败的情况下完成:

  val rollback: DBIO[Unit] = SimpleDBIO(_.connection.rollback)
def runAndRollback[A](dbio: DBIO[A]): DBIO[A] = dbio.andFinally(rollback).transactionally

关于scala - 如何使用 Slick 3 + Specs2 回滚集成测试?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34905455/

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