Maison  >  Article  >  développement back-end  >  Test avec gorm et sqlmock

Test avec gorm et sqlmock

王林
王林avant
2024-02-05 21:39:091090parcourir

使用 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{})
}

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)

}

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

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

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

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)
...

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

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!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer