Maison > développement back-end > Golang > le corps du texte

Test avec gorm et sqlmock

王林
Libérer: 2024-02-05 21:39:09
avant
1127 Les gens l'ont consulté

使用 gorm 和 sqlmock 进行测试

Contenu de la question

J'essaie d'écrire un test pour ma fonction go lambda en utilisant sqlmock et gorm.

C'est la fonctionnalité que je souhaite tester :

func docleanup(con *gorm.db) {
    sixmonthsago := time.now().adddate(0, -6, 0).format("2006-02-01")
    con.where("date_to <= ?", sixmonthsago).delete(&availability{})
    con.where("date_to <= ?", sixmonthsago).delete(&reservation{})
}
Copier après la connexion

Voici mon test :

func testdocleanup(m *testing.t) {
    var mock sqlmock.sqlmock
    var db *sql.db
    var err error

    db, mock, err = sqlmock.new()
    assert.nil(m, err)

    dialector := mysql.new(mysql.config{
        dsn:                       "sqlmock_db_0",
        drivername:                "mysql",
        conn:                      db,
        skipinitializewithversion: true,
    })

    conn, err := gorm.open(dialector, &gorm.config{})
    if err != nil {
        m.errorf("failed to open connection to db: %v", err)
    }

    if conn == nil {
        m.error("failed to open connection to db: conn is nil")
    }

    defer db.close()

    mock.expectquery(fmt.sprintf("delete from availability where date_to <= '%s'", time.now().adddate(0, -6, 0).format("2006-02-01")))
    mock.expectquery(fmt.sprintf("delete from reservations where date_to <= '%s'", time.now().adddate(0, -6, 0).format("2006-02-01")))

    docleanup(conn)

    err = mock.expectationsweremet()
    assert.nil(m, err)

}
Copier après la connexion

Je ne sais pas ce que j’ai fait de mal. C'est la première fois que j'utilise sqlmock. J'ai lu certains endroits et mon code semble bon mais je n'obtiens pas les résultats. Mon erreur était :

Expected nil, but got: &errors.errorString{s:"there is a remaining expectation which was not matched: ExpectedQuery => expecting Query, QueryContext or QueryRow which:\n  - matches sql: 'DELETE FROM availability WHERE date_to <= '2022-13-06''\n  - is without arguments"}
Copier après la connexion

Une idée de ce que j'ai fait de mal ?


Réponse correcte


Le principal problème que je vois réside dans la façon dont vous attendez la requête. au lieu de

    mock.expectquery(fmt.sprintf("delete from availability where date_to <= '%s'", time.now().adddate(0, -6, 0).format("2006-02-01")))
Copier après la connexion

Vous devriez avoir :

    mock.expectbegin()
    mock.expectexec("delete from `availability` where date_to <= ?").
        withargs(time.now().adddate(0, -6, 0).format("2006-02-01")).
        willreturnresult(sqlmock.newresult(0, 0))
    mock.expectcommit()
Copier après la connexion

Cela indiquera à la simulation que vous utilisez des transactions (expectbeginexpectcommit 围绕删除),查询是使用参数进行的(withargs),以及查询的返回结果是什么(willreturnresult)

Il y a d'autres changements subtils, comme `` autour du nom de la table (idiome mysql) et du nom de la table (gorm mettra généralement le nom au pluriel, donc vous êtes soit en availability 上实现 tablename, soit par défaut en disponibilité).

La meilleure façon de voir tous ces problèmes est de modifier docleanup pour renvoyer les erreurs, puis de les voir dans vos tests :

func docleanup(con *gorm.db) error {
    sixmonthsago := time.now().adddate(0, -6, 0).format("2006-02-01")
    tx := con.where("date_to <= ?", sixmonthsago).delete(&availability{})
    if tx.error != nil {
        return tx.error
    }
    tx = con.where("date_to <= ?", sixmonthsago).delete(&reservation{})
    if tx.error != nil {
        return tx.error
    }
    return nil
}
...
    err = docleanup(conn)
    assert.nil(m, err)
...
Copier après la connexion

Faites cela et utilisez le code actuel et vous obtiendrez

Expected nil, but got: &errors.errorString{s:"call to database transaction Begin, was not expected, next expectation is: ExpectedQuery => expecting Query, QueryContext or QueryRow which:\n  - matches sql: 'DELETE FROM availability WHERE date_to <= '2022-13-06''\n  - is without arguments"}
Copier après la connexion

Cela vous indique que sqlmock ne s'attend pas à commencer, et en corrigeant cela, vous obtiendrez les autres erreurs corrigées dans la première partie de cette réponse.

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!

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