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

