繁体   English   中英

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

[英]testing gorm with go-sqlmock issue comparing queries with mock.ExpectQuery and 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文件中发现了一些小问题:

  1. 您编写的 SQL 查询中缺少反引号
  2. 一个额外的; 在查询结束时
  3. 缺少对方法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())
}

然后,如果您尝试运行测试,它应该会起作用。
让我知道这是否解决了您的问题,谢谢!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM