You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

集成测试中如何回滚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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 05:32:34