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

Go使用go-sqlmock模拟带映射的select查询时出现事务及SQL匹配报错如何解决

问题根因

你遇到的报错对应以下几个核心问题:

  • go-sqlmock默认使用正则匹配规则校验SQL语句,你传入的期望SQL里的?是正则特殊字符,会被当作正则规则解析,无法和实际执行的SQL匹配。
  • 你模拟返回的行数据是字符串类型,而业务代码中Project.Id定义为int64类型,类型不匹配会导致Scan操作失败。
  • 如果你业务代码没有显式调用Begin开启事务、Commit提交事务,不需要在测试中添加ExpectBegin和ExpectCommit的期望,否则会出现期望不匹配错误。

解决方案

你可以任选以下一种方式处理SQL匹配问题,同时修正返回值类型即可:

方式1:使用精确匹配模式(推荐,写法更简洁)

初始化sqlmock时指定匹配器为精确匹配,不需要处理正则转义:

// 初始化时添加QueryMatcherOption参数
db, mock, err := sqlmock.New(sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual))

调整后的测试代码如下:

s.sqlmock.
    ExpectQuery("select id from project where id = ? and archived = 1").
    WithArgs(2).
    // 直接传int64类型的1,和业务代码字段类型对齐
    WillReturnRows(sqlmock.NewRows([]string{"id"}).AddRow(int64(1)))

方式2:转义正则特殊字符

如果保留默认的正则匹配模式,把SQL里的?转义为普通字符即可:

s.sqlmock.
    // Go字符串中反斜杠需要转义,所以写为\\?
    ExpectQuery("select id from project where id = \\? and archived = 1").
    WithArgs(2).
    WillReturnRows(sqlmock.NewRows([]string{"id"}).AddRow(int64(1)))

内容的提问来源于stack exchange,提问作者João Manolo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.11 00:12:02