在开发过程中,使用 go-sqlmock 来测试 gorm 的问题是一种常见的需求。go-sqlmock 是一个用于模拟数据库操作的工具,而 gorm 则是一个流行的 Go 语言 ORM 库。在测试过程中,我们经常需要比较查询语句是否符合预期。为了做到这一点,我们可以使用 mock.ExpectQuery 和 regexp.QuoteMeta 来进行比较。这种方法能够帮助我们更好地测试和调试代码,确保程序的正确性和稳定性。接下来,我们将详细介绍如何使用 go-sqlmock 进行 gorm 测试,并展示如何使用 mock.ExpectQuery 和 regexp.QuoteMeta 进行查询语句的比较。
问题内容
我在比较预期查询与 gorm 的真实查询时遇到问题,这是我的代码:
package repository import ( "regexp" "testing" "github.com/data-dog/go-sqlmock" "your_go_root/pkg/domain" "github.com/stretchr/testify/assert" "gorm.io/driver/mysql" "gorm.io/gorm" ) var successgettransaction domain.transaction = domain.transaction{ id: 2, buyerid: 2, sellerid: 5, itemid: 2, messageid: 2, expireddate: "2022-09-010 01:01:00", createdat: "2022-09-08 01:01:00", } func testsuccessgettransactionbyid(t *testing.t) { db, mock, err := sqlmock.new() assert.noerror(t, err) gdb, err := gorm.open(mysql.new(mysql.config{ conn: db, skipinitializewithversion: true, }), &gorm.config{}) assert.noerror(t, err) rows := sqlmock.newrows([]string{"id", "buyer_id", "seller_id", "item_id", "message_id", "expired_date", "created_at"}). addrow(2, 2, 5, 2, 2, "2022-09-010 01:01:00", "2022-09-08 01:01:00") mock.expectquery(regexp.quotemeta("select * from transaction where id = ?;")).willreturnrows(rows) repo := defaultclient(gdb) actualsectionlist, _ := repo.gettransactionbyid(2) assert.equal(t, successgettransaction, actualsectionlist, "ambas listas deberian ser iguales") assert.noerror(t, mock.expectationsweremet()) }
这是模块域:
package domain type transaction struct { id int64 `gorm:"primarykey;column:id"` buyerid int64 `gorm:"column:buyer_id"` sellerid int64 `gorm:"column:seller_id"` itemid int `gorm:"column:item_id"` messageid int `gorm:"column:message_id"` expireddate string `gorm:"column:expired_date"` createdat string `gorm:"column:created_at"` } func (transaction) tablename() string { return "transaction" } type transactionstatus struct { id int64 `gorm:"primarykey;column:id"` transactionid int64 `gorm:"column:transaction_id"` status int `gorm:"column:status"` notificationid int `gorm:"column:notification_id"` createdat string `gorm:"column:created_at"` } func (transactionstatus) tablename() string { return "transaction_status" }
这是我正在测试的功能:
package repository import ( "fmt" "your_go_root/pkg/domain" "gorm.io/gorm" ) type repositoryclient interface { gettransactionbyid(id int) (domain.transaction, error) } type repositoryclient struct { db *gorm.db } func defaultclient(db *gorm.db) repositoryclient { return &repositoryclient{ db: db, } } func (rc repositoryclient) gettransactionbyid(id int) (domain.transaction, error) { trans := domain.transaction{} status := rc.db.where("id = ?", id).find(&trans) if status.error != nil { return domain.transaction{}, status.error } if trans == (domain.transaction{}) { return domain.transaction{}, fmt.errorf("error finding transaction id %v", id) } return trans, nil }
这是我从控制台收到的错误:
Query: could not match actual sql: "SELECT * FROM `transaction` WHERE id = ?" with expected regexp "SELECT \* FROM transaction WHERE id = \?;"[0m[33m[0.218ms] [34;1m[rows:0][0m SELECT * FROM `transaction` WHERE id = 2
在本节中存在一个用“select(.*)”替代的答案,但根据我读到的内容,这不是真正的解决方案
解决方法
让我尝试帮助解决这个问题。我下载了您的所有文件,并且 domain.go
和 repository.go
对我来说看起来不错。
但是,我在 repository_test.go
文件中发现了一些小问题:
- 您编写的 sql 查询中缺少反引号
- 查询末尾额外的
;
- 缺少对
withargs(2)
方法的调用
如果您调整了这些小问题,您应该得到如下所示的代码:
// ... omitted for brevity func TestSuccessGetTransactionByID(t *testing.T) { db, mock, err := sqlmock.New() assert.NoError(t, err) gdb, err := gorm.Open(mysql.New(mysql.Config{ Conn: db, SkipInitializeWithVersion: true, }), &gorm.Config{}) assert.NoError(t, err) rows := sqlmock.NewRows([]string{"id", "buyer_id", "seller_id", "item_id", "message_id", "expired_date", "created_at"}).AddRow(2, 2, 5, 2, 2, "2022-09-010 01:01:00", "2022-09-08 01:01:00") mock.ExpectQuery(regexp.QuoteMeta("SELECT * FROM `transaction` WHERE id = ?")).WithArgs(2).WillReturnRows(rows) repo := DefaultClient(gdb) actualSectionList, _ := repo.GetTransactionByID(2) assert.Equal(t, successGetTransaction, actualSectionList, "ambas listas deberian ser iguales") assert.NoError(t, mock.ExpectationsWereMet()) }
然后,如果您尝试运行测试,它应该可以工作。
如果这解决了您的问题,请告诉我,谢谢!
以上是使用 go-sqlmock 测试 gorm 问题,将查询与mock.ExpectQuery 和 regexp.QuoteMeta 进行比较的详细内容。更多信息请关注PHP中文网其他相关文章!

OpenSSL,作为广泛应用于安全通信的开源库,提供了加密算法、密钥和证书管理等功能。然而,其历史版本中存在一些已知安全漏洞,其中一些危害极大。本文将重点介绍Debian系统中OpenSSL的常见漏洞及应对措施。DebianOpenSSL已知漏洞:OpenSSL曾出现过多个严重漏洞,例如:心脏出血漏洞(CVE-2014-0160):该漏洞影响OpenSSL1.0.1至1.0.1f以及1.0.2至1.0.2beta版本。攻击者可利用此漏洞未经授权读取服务器上的敏感信息,包括加密密钥等。

本文演示了创建模拟和存根进行单元测试。 它强调使用接口,提供模拟实现的示例,并讨论最佳实践,例如保持模拟集中并使用断言库。 文章

本文探讨了GO的仿制药自定义类型约束。 它详细介绍了界面如何定义通用功能的最低类型要求,从而改善了类型的安全性和代码可重复使用性。 本文还讨论了局限性和最佳实践

本文讨论了GO的反思软件包,用于运行时操作代码,对序列化,通用编程等有益。它警告性能成本,例如较慢的执行和更高的内存使用,建议明智的使用和最佳

本文使用跟踪工具探讨了GO应用程序执行流。 它讨论了手册和自动仪器技术,比较诸如Jaeger,Zipkin和Opentelemetry之类的工具,并突出显示有效的数据可视化

本文讨论了GO中使用表驱动的测试,该方法使用测试用例表来测试具有多个输入和结果的功能。它突出了诸如提高的可读性,降低重复,可伸缩性,一致性和A


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

适用于 Eclipse 的 SAP NetWeaver 服务器适配器
将Eclipse与SAP NetWeaver应用服务器集成。

MinGW - 适用于 Windows 的极简 GNU
这个项目正在迁移到osdn.net/projects/mingw的过程中,你可以继续在那里关注我们。MinGW:GNU编译器集合(GCC)的本地Windows移植版本,可自由分发的导入库和用于构建本地Windows应用程序的头文件;包括对MSVC运行时的扩展,以支持C99功能。MinGW的所有软件都可以在64位Windows平台上运行。

Dreamweaver CS6
视觉化网页开发工具

WebStorm Mac版
好用的JavaScript开发工具