Maison > développement back-end > Golang > Comment simuler un ping de base de données sans sqlmock

Comment simuler un ping de base de données sans sqlmock

PHPz
Libérer: 2024-02-12 08:27:27
avant
420 Les gens l'ont consulté

如何在没有 sqlmock 的情况下模拟 db ping

Lors du développement de logiciels, nous rencontrons souvent des situations où nous devons simuler des connexions à des bases de données à des fins de tests. Cependant, il arrive parfois que nous ne disposions pas d’un outil comme sqlmock pour nous aider à atteindre cet objectif. Alors, comment simuler l’opération ping de la base de données sans sqlmock ? Dans cet article, l'éditeur PHP Youzi vous présentera une méthode simple et efficace pour atteindre cet objectif, vous permettant de mener avec succès des tests de simulation de connexions aux bases de données.

Contenu de la question

Je veux savoir comment utiliser mock.mock 重构我的代码以模拟 db.ping(). Je veux d'abord comprendre ce concept sans cadre.

Voici le code que je souhaite tester :

func Connect() (*sql.DB, error) {

    db, err := sql.Open("mysql", "root:secret@tcp(s-maria-db)/s_db")

    if err != nil {
        return nil, err
    }

    for i := 0; i < 60; i++ {
        // I am hoping to mock this portion
        if err := db.Ping(); err == nil {
            break
        }
        time.Sleep(time.Second)
    }

    return db, nil
}
Copier après la connexion

J'ai essayé cet article sur la façon de simuler la commande ping, mais cela ne répond pas réellement à la question. Si c'est le cas, je ne comprends pas la solution car elle fonctionne pour mon code.

Solution de contournement

Vous devez utiliser une fonction distincte pour le ping, et elle doit accepter une interface afin que vous puissiez transmettre conditionnellement un vrai *sql.db ou un simulacre. En effet, vous ne pouvez pas remplacer les méthodes sur une structure.

// connect opens a connection to the database.
func connect() (*sql.db, error) {
    return sql.open("mysql", "root:secret@tcp(s-maria-db)/s_db")
}

// pinger defines an interface for pinging.
type pinger interface {
    ping() error
}

// ping attempts to ping the database, trying several times before failing.
func ping(p pinger) error {
    const maxattempts = 60
    var err error
    for i := 0; i < maxattempts; i++ {
        if err = p.ping(); err == nil {
            return nil
        }
        if i < maxattempts - 1 {
            time.sleep(time.second)
        }
    }
    return err
}
Copier après la connexion
func main() {
    if err := run(); err != nil {
        log.fatal(err)
    }
}

func run() error {
    db, err := connect()
    if err != nil {
        return fmt.errorf("connecting to db: %w", err)
    }
    defer db.close()

    if err = ping(db); err != nil {
        return fmt.errorf("pinging db: %w", err)
    }
    
    ...
}
Copier après la connexion
type mockDB struct {
    mock.Mock
}

func (m *mockDB) Ping() error {
    args := m.Called()
    return args.Error(0)
}

func TestPing(t *testing.T) {
    db := &mockDB{}
    db.On("Ping").Return(...)

    err := Ping(db)

    ...
    db.AssertExpectations(t)
}
Copier après la connexion

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