Maison > développement back-end > Golang > Test sqlmock de la clause de suppression Gorm

Test sqlmock de la clause de suppression Gorm

WBOY
Libérer: 2024-02-08 22:30:31
avant
859 Les gens l'ont consulté

Gorm 删除子句 sqlmock 测试

L'éditeur PHP Xinyi vous présente le test sqlmock de la clause de suppression Gorm. Gorm est un excellent framework ORM dans le langage Go, et sqlmock est un outil de test pour Gorm, utilisé pour simuler les opérations de base de données. Lors du développement de Gorm, nous devons souvent tester l'opération de suppression de base de données. À ce stade, nous pouvons utiliser sqlmock pour simuler l'opération de suppression de base de données pour les tests unitaires et les tests d'intégration. Cet article vous présentera en détail comment utiliser Gorm et sqlmock pour tester les clauses de suppression, vous aidant ainsi à mieux effectuer les travaux de développement liés aux bases de données.

Contenu de la question

J'ai une suppression de gorm, le résultat renvoyé est :

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)
Copier après la connexion

Les tests avec des clauses échouent désormais toujours. Par exemple :

sqlMock.ExpectExec(`DELETE`)
    .WithArgs(expirationDate)
    .WillReturnResult(sqlmock.NewResult(1, 1))
Copier après la connexion

Erreur de réception :

"L'appel de la requête 'supprimer de "mes_utilisateurs" où créé_at < $1 renvoyant "email"' avec les paramètres [{name : ordinal:1 value:2023-01-18 06:15:34.694274 +0000 utc}] n'est pas attendu, L'attente suivante est : attenduexec => ; attend exec ou execcontext où : n - correspond à sql : 'delete'n - prend les arguments : n 0 - 2023-01-18 06:15:34.694274 +0000 utc n - devrait renvoyer avec les résultats pour : n lastinsertid : 1n lignes affectées : 1"

J'ai essayé de nombreuses autres attentes sqlmock mais elles avaient des problèmes similaires. De plus, nous n'avons aucune valeur de retour dans expectexec, uniquement dans expectquery... Quelqu'un doit-il tester les requêtes gorm avec des clauses ?

Solution

J'ai su gérer avec succès vos besoins. Tout d'abord, permettez-moi de partager le fichier que j'ai écrit, puis je vous expliquerai toutes les modifications pertinentes. Ces fichiers sont destinés à une utilisation en production 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
}
Copier après la connexion

Comme vous n'avez pas fourni le dossier complet, j'ai essayé de deviner ce qui manque.

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)
    }
}
Copier après la connexion

Voici d'autres changements qui méritent d'être mentionnés :

  1. J'ai instancié anytime selon la documentation (vous pouvez voir le lien dans les commentaires).
  2. J'ai deviné les paramètres pour dbmockgormdb mais je pense qu'ils devraient être à peu près les mêmes.
  3. J'ai changé l'utilisation de expectexec en expectquery car nous renverrons l'ensemble de résultats spécifié par la méthode expectexec 的用法切换为 expectquery,因为我们将返回 clauses 文件中 repo.go dans le fichier clauses.
  4. Vous devez mettre expectquery 包装在 expectbeginexpectcommit dedans.
  5. Enfin, notez la différence dans la façon dont les pilotes attendent les paramètres dans les instructions SQL. Dans le code de production, vous avez la possibilité d'utiliser ?。但在测试代码中,只能使用?, sinon il ne se comporte pas comme prévu.

J'espère que cela vous aidera, sinon faites-le-moi savoir !

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:stackoverflow.com
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal