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

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

PHPz
PHPzavant
2024-02-12 08:27:27356parcourir

如何在没有 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
}

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

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