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

使用sqlmock进行SQL更新操作的单元测试失败问题排查

解决sqlmock测试GORM UPDATE操作失败的问题

看起来你踩了sqlmock和GORM配合时的一个常见小坑——用错了sqlmock的期望方法!

问题根源

GORM执行Save方法进行更新操作时,底层调用的是数据库的Exec方法(因为UPDATE属于写操作,不会返回结果集),但你在测试里用了ExpectQuery,这个方法是用来匹配Query/QueryRow这类查询操作的(比如SELECT)。所以sqlmock会认为实际调用的Exec不符合你预期的Query,导致测试失败。

修正后的测试代码

把ExpectQuery换成ExpectExec就可以解决这个问题,调整后的测试函数如下:

func (s *Suite) TestPutTag() {
    tag := Tag{Id: 2, Name: "Test Tag 2"}
    s.mock.ExpectBegin()
    // 把ExpectQuery替换为ExpectExec,适配UPDATE这类写操作
    s.mock.ExpectExec("UPDATE `tags` SET `name` = ? WHERE `tags`.`id` = ? AND ((id=?))").
        WithArgs(tag.Name, tag.Id, tag.Id).
        WillReturnResult(sqlmock.NewResult(1, 1)) // 可选:模拟返回受影响行数
    s.mock.ExpectCommit()
    err := PutTag(&tag)
    require.NoError(s.T(), err)
}

额外说明

  • ExpectQuery:对应SQL查询类操作(SELECT、SHOW等会返回结果集的语句),底层匹配Query/QueryContext/QueryRow方法。
  • ExpectExec:对应SQL写操作(INSERT、UPDATE、DELETE等不返回结果集的语句),底层匹配Exec/ExecContext方法。
  • 如果你需要模拟更新操作的返回结果(比如受影响行数),可以用WillReturnResult(sqlmock.NewResult(1, 1)),第一个参数是最后插入的ID(UPDATE场景下可随意填写),第二个是受影响的行数。

内容的提问来源于stack exchange,提问作者Maira Saliyeva

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 07:13:54