集成测试中如何回滚Skunk事务?(缺失隐式Origin)
解决Skunk事务回滚时缺失隐式
Origin的问题 问题原因
Skunk的rollback方法依赖隐式的skunk.util.Origin实例,用于追踪SQL操作的代码位置。在Scala 2中,Skunk通过编译期宏自动生成这个隐式实例,但Scala 3的宏系统逻辑不同,导致需要手动提供或导入对应的隐式规则。
解决方法
你可以通过以下两种方式获取Origin隐式实例:
1. 显式生成Origin
在调用rollback的作用域内,直接定义隐式Origin:
import skunk.util.Origin // 在测试方法或测试类的作用域中添加 implicit val origin: Origin = Origin.current
Origin.current会基于当前代码位置自动生成实例,满足Skunk对来源追踪的需求。
2. 导入Skunk的语法包
导入Skunk提供的全量语法包,其中包含自动生成Origin的隐式规则:
import skunk.syntax.all._
这个包会为所有SQL操作自动注入所需的Origin隐式,无需手动定义。
为什么文档示例无此问题?
Skunk官方文档中的示例基于Scala 2编写,Skunk在Scala 2环境下会通过宏自动为每个SQL操作生成Origin实例,因此无需显式处理。而Scala 3的宏系统与Scala 2存在差异,当前版本的Skunk尚未完全适配Scala 3的自动宏生成逻辑,因此需要手动补充隐式Origin。
代码修改示例
假设你的测试代码结构如下,添加隐式Origin后即可正常编译:
import cats.effect._ import munit.CatsEffectSuite import skunk._ import skunk.util.Origin import scala.testcontainers.postgres.PostgresContainer class PostgresIntegrationTest extends CatsEffectSuite { private val container = PostgresContainer("postgres:15") private val sessionResource: Resource[IO, Session[IO]] = Session.single( host = container.host, port = container.mappedPort(5432), user = container.username, database = container.databaseName, password = Some(container.password) ) test("test with transaction rollback") { // 显式添加隐式Origin implicit val origin: Origin = Origin.current sessionResource.use { session => session.transaction.use { tx => for { // 执行测试用的SQL操作 _ <- tx.execute(sql"INSERT INTO test VALUES (1)".command) // 回滚事务 _ <- tx.rollback } yield assert(true) } } } }
内容的提问来源于stack exchange,提问作者Jake
相关产品推荐
相关产品推荐

