Heim  >  Artikel  >  Backend-Entwicklung  >  Testen Sie Gorm-Probleme mit go-sqlmock und vergleichen Sie Abfragen mit mock.ExpectQuery und regexp.QuoteMeta

Testen Sie Gorm-Probleme mit go-sqlmock und vergleichen Sie Abfragen mit mock.ExpectQuery und regexp.QuoteMeta

WBOY
WBOYnach vorne
2024-02-11 12:48:08445Durchsuche

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

Während des Entwicklungsprozesses ist es eine häufige Anforderung, go-sqlmock zum Testen von Gorm-Problemen zu verwenden. go-sqlmock ist ein Tool zur Simulation von Datenbankoperationen, während gorm eine beliebte ORM-Bibliothek der Go-Sprache ist. Während des Testprozesses müssen wir häufig vergleichen, ob die Abfrageanweisung den Erwartungen entspricht. Dazu können wir zum Vergleich „mock.ExpectQuery“ und „regexp.QuoteMeta“ verwenden. Diese Methode kann uns helfen, den Code besser zu testen und zu debuggen und die Korrektheit und Stabilität des Programms sicherzustellen. Als Nächstes stellen wir detailliert vor, wie man go-sqlmock für Gorm-Tests verwendet, und zeigen, wie man mit mock.ExpectQuery und regexp.QuoteMeta Abfrageanweisungen vergleicht.

Frageninhalt

Ich habe ein Problem beim Vergleich der erwarteten Abfrage mit der tatsächlichen Abfrage von Gorm. Hier ist mein Code:

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())
}

Dies ist die Moduldomäne:

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"
}

Das ist die Funktion, die ich teste:

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
}

Dies ist der Fehler, den ich von der Konsole erhalte:

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

In diesem Abschnitt gibt es stattdessen eine Antwort mit „select(.*)“, aber nach dem, was ich gelesen habe, ist das keine echte Lösung.

Workaround

Lassen Sie mich versuchen, bei der Lösung dieses Problems zu helfen. Ich habe alle Ihre Dateien heruntergeladen und domain.gorepository.go sieht für mich gut aus.
Allerdings habe ich einige kleine Probleme in der repository_test.go-Datei gefunden:

  1. In der von Ihnen geschriebenen SQL-Abfrage fehlen Backticks
  2. Zusätzliches ;
  3. am Ende der Abfrage
  4. Fehlender Aufruf der withargs(2)Methode

Wenn Sie diese kleinen Dinge anpassen, sollten Sie am Ende einen Code erhalten, der so aussieht:

// ... 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())
}

Wenn Sie dann versuchen, den Test auszuführen, sollte es funktionieren.
Wenn dies Ihr Problem löst, lassen Sie es mich bitte wissen, danke!

Das obige ist der detaillierte Inhalt vonTesten Sie Gorm-Probleme mit go-sqlmock und vergleichen Sie Abfragen mit mock.ExpectQuery und regexp.QuoteMeta. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:stackoverflow.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen