Gorm-Löschklausel, SQLMock-Test

WBOY
Freigeben: 2024-02-08 22:30:31
nach vorne
816 Leute haben es durchsucht

Gorm 删除子句 sqlmock 测试

PHP-Editor Xinyi stellt Ihnen den Gorm-Löschklausel-SQLMock-Test vor. Gorm ist ein hervorragendes ORM-Framework in der Go-Sprache und sqlmock ist ein Testtool für Gorm, das zur Simulation von Datenbankvorgängen verwendet wird. Bei der Entwicklung von Gorm müssen wir häufig den Datenbanklöschvorgang testen. Zu diesem Zeitpunkt können wir SQLMock verwenden, um den Datenbanklöschvorgang für Unit-Tests und Integrationstests zu simulieren. In diesem Artikel erfahren Sie ausführlich, wie Sie mit Gorm und sqlmock Löschklauseln testen und so datenbankbezogene Entwicklungsarbeiten besser durchführen können.

Frageninhalt

Ich habe einen Gorm gelöscht, das Rückgabeergebnis ist:

expirationdate := time.now().utc().add(-(48 * time.hour))
var deletedusers users
res := gormdb.withcontext(ctx).
    table("my_users").
    clauses(clause.returning{columns: []clause.column{{name: "email"}}}).
    where("created_at < ?", expirationdate).
    delete(&deletedusers)
Nach dem Login kopieren

Tests mit Klauseln schlagen jetzt immer fehl. Zum Beispiel:

sqlMock.ExpectExec(`DELETE`)
    .WithArgs(expirationDate)
    .WillReturnResult(sqlmock.NewResult(1, 1))
Nach dem Login kopieren

Empfangsfehler:

„Der Aufruf der Abfrage „delete from „my_users“ wherecreated_at < Die nächste Erwartung lautet: erwartet exec => erwartet exec oder execcontext wobei: n – entspricht sql: 'delete'n – akzeptiert Argumente: n 0 – 2023-01-18 06:15:34.694274 +0000 utc n – sollte mit Ergebnissen zurückgegeben werden für: n lastinsertid: 1n betroffene Zeilen: 1"

Ich habe viele andere SQLMock-Erwartungen ausprobiert, aber sie hatten ähnliche Probleme. Außerdem haben wir in Expectexec keinen Rückgabewert, nur in Expectquery ... Muss jemand Gorm-Abfragen mit Klauseln testen?

Lösung

Ich konnte Ihre Bedürfnisse erfolgreich bewältigen. Lassen Sie mich zunächst die Datei teilen, die ich geschrieben habe, und dann werde ich Sie durch alle relevanten Änderungen führen. Diese Dateien sind für den Produktionsgebrauch bestimmt repo.go 和用于测试代码的 repo_test.go.

repo.go

package gormdelete

import (
    "context"
    "time"

    "gorm.io/gorm"
    "gorm.io/gorm/clause"
)

type users struct {
    email string
}

func delete(ctx context.context, gormdb *gorm.db) error {
    expirationdate := time.now().utc().add(-(48 * time.hour))

    var deletedusers users
    res := gormdb.withcontext(ctx).table("my_users").clauses(clause.returning{columns: []clause.column{{name: "email"}}}).where("created_at < ?", expirationdate).delete(&deletedusers)
    if res.error != nil {
        return res.error
    }
    return nil
}
Nach dem Login kopieren

Da Sie nicht die vollständige Datei bereitgestellt haben, habe ich versucht zu erraten, was fehlt.

repo_test.go

package gormdelete

import (
    "context"
    "database/sql/driver"
    "testing"
    "time"

    "github.com/DATA-DOG/go-sqlmock"
    "github.com/stretchr/testify/assert"
    "gorm.io/driver/postgres"
    "gorm.io/gorm"
)

// this is taken directly from the docs
// https://github.com/DATA-DOG/go-sqlmock#matching-arguments-like-timetime
type AnyTime struct{}

// Match satisfies sqlmock.Argument interface
func (a AnyTime) Match(v driver.Value) bool {
    _, ok := v.(time.Time)
    return ok
}

func TestDelete(t *testing.T) {
    db, mock, err := sqlmock.New()
    if err != nil {
        t.Fatalf("an error was not expected: %v", err)
    }

    conn, _ := db.Conn(context.Background())
    gormDb, err := gorm.Open(postgres.New(postgres.Config{
        Conn: conn,
    }))

    row := sqlmock.NewRows([]string{"email"}).AddRow("<a href="https://www.php.cn/link/89fee0513b6668e555959f5dc23238e9" class="__cf_email__" data-cfemail="9febfaecebdffae7fef2eff3fab1fcf0f2">[email&#160;protected]</a>")
    mock.ExpectBegin()
    mock.ExpectQuery("DELETE FROM \"my_users\" WHERE created_at < ?").WithArgs(AnyTime{}).WillReturnRows(row)
    mock.ExpectCommit()

    err = Delete(context.Background(), gormDb)

    assert.Nil(t, err)
    if err = mock.ExpectationsWereMet(); err != nil {
        t.Errorf("not all expectations were met: %v", err)
    }
}
Nach dem Login kopieren

Hier sind weitere erwähnenswerte Änderungen:

  1. Ich habe anytime gemäß der Dokumentation instanziiert (Sie können den Link in den Kommentaren sehen).
  2. Ich habe die Einstellungen für dbmockgormdb noch einmal erraten, aber ich denke, sie sollten ungefähr gleich sein.
  3. Ich habe die Verwendung von expectexec auf expectquery umgestellt, da wir die von der expectexec 的用法切换为 expectquery,因为我们将返回 clauses 文件中 repo.go-Methode angegebene Ergebnismenge in der Datei clauses zurückgeben.
  4. Sie müssen expectquery 包装在 expectbeginexpectcommit eingeben.
  5. Beachten Sie abschließend den Unterschied darin, wie Treiber Parameter in SQL-Anweisungen erwarten. Im Produktionscode haben Sie die Möglichkeit, ?。但在测试代码中,只能使用? zu verwenden, andernfalls verhält es sich nicht wie erwartet.

Ich hoffe, es hilft, wenn nicht, lass es mich bitte wissen!

Das obige ist der detaillierte Inhalt vonGorm-Löschklausel, SQLMock-Test. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Quelle:stackoverflow.com
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage
Über uns Haftungsausschluss Sitemap
Chinesische PHP-Website:Online-PHP-Schulung für das Gemeinwohl,Helfen Sie PHP-Lernenden, sich schnell weiterzuentwickeln!