gpt4 book ai didi

scala - 在交易中包装测试

转载 作者:行者123 更新时间:2023-12-02 03:27:09 28 4
gpt4 key购买 nike

假设我有几个测试做这样的事情

"should do something with the database" in new WithApplication {
DB.withTransaction { implicit con =>
// Query the database.
// Perform my tests.

// Rollback the transaction to return database to initial state
con.rollback()
}
}

我不想记得将我所有的数据库测试包装在一个事务中并在每个测试结束时手动调用 con.rollback()

相反,我尝试编写一个将整个测试包装在一个事务中的特征,这样我就可以像这样编写我的测试

"do something to the database" in new WithApplication with DatabaseTest {
SQL("...").execute()
}

这是我目前的情况

trait DatabaseTest extends Around with Scope {
abstract override def around[T: AsResult](test: => T): Result = {
super.around = {
import play.api.Play.current

DB.withTransaction { implicit con =>
val result = test
con.rollback()
result
}
}
}

然而,当我尝试运行上面的测试时,我得到了这个错误

could not find implicit value for parameter connection: java.sql.Connection

所以我的问题是我尝试做的事情是否可行,如果可行,我的代码有什么问题,我需要更改什么才能使其正常工作。

最佳答案

Scala 中的隐式并不像在 Java 应用程序服务器中添加到某种上下文的事务那样神奇,相反,它们通过告诉编译器“如果缺少类型 T 的参数,请查看我所在的范围”来工作'm 用于标记为隐式的类型 T 的值"。

这就是为什么看起来像这样的常用代码有效的原因:

def doStuff()(implicit aConnection: Connection) = ???

DB.withTransaction { implicit theConnection =>
doStuff() // secretly the compiler adds theConnection here
}

但这也意味着你不能免费得到它,因为你继承的一些类有一个隐式连接,它需要在范围内才能可用,而且 Around 不允许你更改测试的签名,所以你不能使用它真正将其纳入范围。

一种方法可能是避免使用 withTransaction,而是在一个范围内使用 DB.getConnection,就像这样(从我的脑海中,所以可能不准确/编译):

trait Tx extends Scope with After {
implicit lazy val conn = DB.getConnection(autocommit = false)

override def after() = conn.rollback()
}

然后在您的测试中使用它,这将隐式连接到作用域中:

"something something" in new Tx {
SQL("...").execute()
}

关于scala - 在交易中包装测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29751780/

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