记录工作中使用sqlmock和gorm遇到的一些问题

正则匹配

  • sqlmock中默认使用的是正则表达式去匹配sql语句
    sqlmock.ExpectQuery()sqlmock.ExpectExec()等,如果想直接匹配sql语句需要加上regexp.QuoteMeta()
    例子:
//这个是使用正则来匹配sql语句,需要使用“\\”来转义字符
mock.ExpectQuery("SELECT \\* FROM `cmdb_app` WHERE app_code = \\? AND is_deleted = \\? ORDER BY `cmdb`\\.`id` limit 1")
//直接匹配sql语句
mock.ExpectQuery(regexp.QuoteMeta("SELECT * FROM `cmdb_app` WHERE app_code = ? AND is_deleted = ? ORDER BY `cmdb`.`id` limit 1"))

mock所有的sql语句

当我想测试一个在mysql中创建app记录的函数时,我只模拟了insert语句的返回情况,忽略了创建app记录前还有个select语句判断当前数据库中是否已有app记录
当前的代码:

mock.ExpectBegin()
mock.ExpectExec("INSERT INTO").WillReturnResult(sqlmock.NewResult(1, 1))
mock.ExpectCommit()

所以导致了下面这个错误

call to Query 'SELECT * FROM `cmdb_app` WHERE app_code = ? and is_deleted = 0 ORDER BY `cmdb_app`.`id` LIMIT 1' with args [{Name: Ordinal:1 Value:app1}], was not expected, next expectation is: ExpectedExec => expecting Exec or ExecContext which:
  - matches sql: 'INSERT INTO'
  - is without arguments
  - should return Result having:
      LastInsertId: 1
      RowsAffected: 1

修改代码

// 在mock.ExpectExec("INSERT INTO")之前加上下面代码
mock.ExpectQuery("SELECT").WillReturnRows(sqlmock.NewRows([]string{"id", "app_code", "app_name", "status", "business", "app_type", "desc", "language"}))

运行成功:

=== RUN   TestCreateApp
--- PASS: TestCreateApp (0.00s)
=== RUN   TestCreateApp/create_success
    --- PASS: TestCreateApp/create_success (0.00s)
PASS

注意关闭内联优化

有时会遇到mock失效的情况,这个问题一般是内联导致的。

什么是内联?

为了减少函数调用时的堆栈等开销,对于简短的函数,会在编译时,直接内嵌调用的代码。
如下面例子未使用内联优化:

[root@DESKTOP-GG9HG4Q cmdb_service]# go test 
E
Errors:
  * /root/Projections/Athena/src/service/cmdb_service/cmdb_environment_test.go 
  Line 167: - runtime error: invalid memory address or nil pointer dereference 
  goroutine 8 [running]:
        /home/gopath/pkg/mod/github.com/smartystreets/goconvey@v1.6.4/convey/reporting/reports.go:148 +0x6f
        /home/gopath/pkg/mod/github.com/smartystreets/goconvey@v1.6.4/convey/reporting/reports.go:121 +0x75
        /home/gopath/pkg/mod/github.com/smartystreets/goconvey@v1.6.4/convey/context.go:235 +0x13f

加上-gcflags=all=-l后关闭内联优化

[root@DESKTOP-GG9HG4Q cmdb_service]# go test -gcflags=all=-l
.
1 total assertion

PASS
ok      athena/src/service/cmdb_service 0.005s
  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

枫花海

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值