Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Uji isu gorm menggunakan go-sqlmock, membandingkan pertanyaan dengan mock.ExpectQuery dan regexp.QuoteMeta

Uji isu gorm menggunakan go-sqlmock, membandingkan pertanyaan dengan mock.ExpectQuery dan regexp.QuoteMeta

WBOY
WBOYke hadapan
2024-02-11 12:48:08445semak imbas

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

Semasa proses pembangunan, adalah keperluan biasa untuk menggunakan go-sqlmock untuk menguji masalah gorm. go-sqlmock ialah alat untuk mensimulasikan operasi pangkalan data, manakala gorm ialah perpustakaan ORM bahasa Go yang popular. Semasa proses ujian, kita sering perlu membandingkan sama ada pernyataan pertanyaan memenuhi jangkaan. Untuk melakukan ini, kita boleh menggunakan mock.ExpectQuery dan regexp.QuoteMeta sebagai perbandingan. Kaedah ini boleh membantu kami menguji dan nyahpepijat kod dengan lebih baik dan memastikan ketepatan dan kestabilan program. Seterusnya, kami akan memperkenalkan secara terperinci cara menggunakan go-sqlmock untuk ujian gorm, dan menunjukkan cara menggunakan mock.ExpectQuery dan regexp.QuoteMeta untuk membandingkan pernyataan pertanyaan.

Kandungan soalan

Saya menghadapi masalah membandingkan pertanyaan yang dijangkakan dengan pertanyaan sebenar gorm, berikut kod saya:

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

Ini ialah domain modul:

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

Ini adalah ciri yang saya uji:

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
}

Ini adalah ralat yang saya terima daripada konsol:

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

Terdapat jawapan dengan "pilih(.*)" sebaliknya dalam bahagian ini, tetapi daripada apa yang saya baca, itu bukan penyelesaian sebenar

Penyelesaian

Izinkan saya cuba membantu menyelesaikan masalah ini. Saya memuat turun semua fail anda dan domain.gorepository.go kelihatan baik bagi saya.
Walau bagaimanapun, saya menemui beberapa isu kecil dalam fail repository_test.go:

  1. Kunci belakang tiada dalam pertanyaan sql yang anda tulis
  2. Tambahan ;
  3. pada akhir pertanyaan
  4. Panggilan tiada ke withargs(2) kaedah

Jika anda melaraskan perkara kecil ini, anda sepatutnya mendapat kod yang kelihatan seperti ini:

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

Kemudian jika anda cuba menjalankan ujian itu pasti berkesan.
Sila beritahu saya jika ini menyelesaikan masalah anda, terima kasih!

Atas ialah kandungan terperinci Uji isu gorm menggunakan go-sqlmock, membandingkan pertanyaan dengan mock.ExpectQuery dan regexp.QuoteMeta. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:stackoverflow.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam