使用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
相关产品推荐
相关产品推荐

