使用 gosqlmock 测试 gorm 问题,将查询与mock.ExpectQuery 和 regexp.QuoteMeta 进行比较

2024年 2月 11日 35.3k 0

使用 go-sqlmock 测试 gorm 问题,将查询与mock.expectquery 和 regexp.quotemeta 进行比较

在开发过程中,使用 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.gorepository.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 进行比较的详细内容,更多请关注每日运维网(www.mryunwei.com)其它相关文章!

    相关文章

    JavaScript2024新功能:Object.groupBy、正则表达式v标志
    PHP trim 函数对多字节字符的使用和限制
    新函数 json_validate() 、randomizer 类扩展…20 个PHP 8.3 新特性全面解析
    使用HTMX为WordPress增效:如何在不使用复杂框架的情况下增强平台功能
    为React 19做准备:WordPress 6.6用户指南
    如何删除WordPress中的所有评论

    发布评论