Maison  >  Article  >  développement back-end  >  Discutez de l'utilisation de Mock dans Golang

Discutez de l'utilisation de Mock dans Golang

PHPz
PHPzoriginal
2023-04-23 19:29:061549parcourir

Golang est un langage de programmation open source à typage statique qui est bien accueilli et apprécié par de plus en plus de développeurs. Lors de l’écriture du code de test, il est souvent nécessaire de traiter des données simulées. Dans cet article, nous approfondirons l'utilisation de Mock dans Golang et comment traiter les données Mock dans différents scénarios.

1. Pourquoi Mocking est-il nécessaire ?

Pendant le processus de test, nous rencontrons souvent le besoin de tester du code qui repose sur des services tiers (tels que des API, des bases de données, des files d'attente de messages, etc.). Cela nous oblige à utiliser la technologie Mocking pour simuler les résultats de réponse de ces services dépendants afin de garantir que le code de test peut s'exécuter de manière indépendante et rapide.

De plus, Mocking peut également être utilisé pour tester les conditions aux limites du code (telles que des situations anormales, telles que des données d'entrée ne répondant pas aux exigences, etc.) afin d'améliorer la robustesse et la fiabilité du code.

2. Outils de moquerie dans Golang

Il existe de nombreux outils de moquerie parmi lesquels choisir dans Golang. Certains des outils les plus populaires sont :

  1. témoigner : fournit des fonctions de moquerie et d'assertion, qui sont très faciles à utiliser. Il peut être utilisé pour simuler des sources de données et des sorties courantes telles que des bases de données, des requêtes HTTP et d'autres services.
  2. moquerie : Relativement parlant, cet outil est plus léger. Il peut générer du code Mock rapidement et avec précision et prend en charge la fonction Mocking d'exécution. De plus, Mockery prend en charge la sortie basée sur un modèle lors de la génération de code Mock, ce qui peut fournir aux utilisateurs des options plus personnalisables.
  3. mockery/mockery : Par rapport aux moqueries ci-dessus, cet outil est davantage axé sur les besoins des développeurs du langage Go. Il fournit une API plus flexible qui permet la testabilité du code. En plus de prendre en charge les méthodes d'interface fictives, Mockery peut également simuler des dépendances externes non intrusives.

3. Utilisez testify pour Mocking

Ci-dessous, nous utiliserons testify comme outil de moquerie et utiliserons un exemple pour démontrer comment utiliser la technologie Mocking pour tester le code.

Nous supposons que la fonction suivante s'appuie sur une API HTTP externe pour obtenir des données :

func getOrderDetail(orderID int) (OrderDetail, error){
    resp, err := http.Get("https://api.example.com/order/"+strconv.Itoa(orderID))
    if err != nil {
        return nil, err
    }
    defer resp.Body.Close()
    
    if resp.StatusCode != http.StatusOK {
        return nil, fmt.Errorf("getOrderDetail API returns error status code: %d", resp.StatusCode)
    }

    var orderDetail OrderDetail
    return orderDetail, json.NewDecoder(resp.Body).Decode(&orderDetail)
}

Afin de tester cette fonction, nous devrons simuler la requête HTTP. testify fournit deux méthodes, MockHTTPServer et RoundTripper, pour implémenter la simulation des requêtes HTTP.

Tout d'abord, voyons comment utiliser MockHTTPServer :

func TestGetOrderDetail(t *testing.T) {
    // 创建一个mock server
    server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        // 按照需要返回数据
        if r.URL.Path == "/order/123" {
            fmt.Fprintln(w, "{\"orderID\":123,\"createDate\":\"2021-01-01\"}")
        } else {
            http.Error(w, "not found", http.StatusNotFound)
        }
    }))
    defer server.Close()

    // 将http client的请求地址指向mock server
    oldClient := http.DefaultClient
    http.DefaultClient = server.Client()
    defer func() { http.DefaultClient = oldClient }()

    // 调用 getOrderDetail() 函数
    orderDetail, err := getOrderDetail(123)

    // 对 getOrderDetail() 的返回结果进行断言
    assert.Nil(t, err)
    assert.Equal(t, 123, orderDetail.OrderID) // 假设OrderDetail中包含了字段 OrderID

    // 按照需要进行其他断言
}

Dans cet exemple, nous utilisons la méthode httptest.NewServer() pour créer un serveur fictif, puis simulons le retour de la réponse et du code d'état de la requête HTTP dans son handlerFunc() .

Ensuite, nous pointons http.DefaultClient vers le serveur fictif afin que lorsque getOrderDetail() est appelé pendant le test, il puisse envoyer une requête au serveur fictif.

Enfin, nous utilisons la méthode d'assertion de testify pour vérifier les résultats renvoyés afin de garantir l'exactitude de la fonction.

En plus de MockHTTPServer, testify fournit également la méthode RoundTripper pour simuler les requêtes HTTP. Cette méthode offre un moyen plus flexible et contrôlable de simuler les requêtes HTTP. Les utilisateurs peuvent personnaliser la mise en œuvre de RoundTripper pour passer à la source de données fictive à tout moment afin de mieux contrôler le processus de test. Les lecteurs peuvent se référer à la documentation officielle de Témoignage pour en savoir plus sur l'utilisation de cette méthode.

4. Utiliser la moquerie pour se moquer

En plus de témoigner, on peut aussi utiliser la moquerie pour se moquer. Mockery est basé sur la bibliothèque simulée intégrée au langage (http://golang.org/pkg/mock/) et fournit un outil de génération de code qui peut générer un cadre pour du code Mock réutilisable. Mockery prend en charge la génération de codes Mock d'interface et de dépendances externes. Nous présenterons le mode d'interface Mocking à titre d'exemple ci-dessous.

Tout d'abord, nous devons installer l'outil de génération de moquerie :

go get github.com/vektra/mockery/v2/.../

Ensuite, nous définissons une interface et y ajoutons une méthode :

type OrderDetailFetcher interface {
    FetchOrderDetail(orderID int) (OrderDetail, error)
}

Ensuite, dans le répertoire racine du projet, exécutez la commande suivante pour générer du code Mock :

mockery --name OrderDetailFetcher

Cela générera automatiquement un fichier nommé "mock_orderdetailfetcher.go", qui contient déjà le code Mock généré automatiquement. Nous pouvons utiliser ce code Mock dans n'importe quel code pour implémenter les données Mock de l'interface et terminer la tâche de test.

Enfin, nous donnons un exemple spécifique pour montrer comment utiliser la moquerie pour générer du code Mocking :

type OrderDetail struct {
    OrderID     int
    CreateDate  string
}

type OrderDetailFetcher interface {
    FetchOrderDetail(orderID int) (OrderDetail, error)
}

func GetOrderDetail(fetcher OrderDetailFetcher, orderID int) (OrderDetail, error) {
    orderDetail, err := fetcher.FetchOrderDetail(orderID)
    if err != nil {
        return OrderDetail{}, err
    }

    return orderDetail, nil
}

Dans cet exemple, nous définissons une interface nommée "OrderDetailFetcher" et implémentons une fonction GetOrderDetail(), Cette fonction nécessite l'utilisation de FetchOrderDetail( ) dans l'interface OrderDetailFetcher pour obtenir les détails de la commande. Nous pouvons utiliser la commande mockery pour générer automatiquement le code Mock pour la méthode FetchOrderDetail() :

mockery --name OrderDetailFetcher

Cette commande générera un fichier nommé "mock_orderdetailfetcher.go" dans le répertoire courant, qui contient le code Mock généré automatiquement. Il nous suffit de combiner le code Mock avec notre code de test pour terminer la tâche de test fonctionnel.

func TestGetOrderDetail(t *testing.T) {
    orderDetail := OrderDetail{OrderID: 123, CreateDate: "2021-01-01"}

    // 创建一个mock对象
    mockOrderDetailFetcher := &mocks.OrderDetailFetcher{}

    // 设定mock对象的mock调用及对应的返回结果
    mockOrderDetailFetcher.On("FetchOrderDetail", 123).Return(orderDetail, nil)

    // 调用GetOrderDetail()函数
    result, err := GetOrderDetail(mockOrderDetailFetcher, 123)

    // 校验返回结果及错误码
    assert.Nil(t, err)
    assert.Equal(t, orderDetail, result)
}

Dans cet exemple, nous définissons un objet mockOrderDetailFetcher et utilisons la méthode On() dans la bibliothèque Mock pour spécifier une règle d'appel spécifique et le résultat correspondant pour sa méthode FetchOrderDetail() - dans orderID est 123. Dans ce cas, l'objet orderDetail est restitué. Lors de l'obtention du FetchOrderDetail(123) de mockOrderDetailFetcher, le code de test renverra directement l'objet orderDetail préconfiguré. Enfin, nous utilisons la méthode d'assertion de testify pour vérifier les résultats.

Résumé

Dans cet article, nous présentons les connaissances pertinentes de Mocking dans Golang et des outils Mocking courants, ainsi que la façon d'utiliser les outils de témoignage et de moquerie pour effectuer des opérations Mocking et effectuer des tests Mock de la fonction cible. Grâce à une application raisonnable et correcte de la technologie Mocking, nous pouvons améliorer la lisibilité, la robustesse, la fiabilité et d'autres aspects du code. Dans le même temps, Mocking peut également nous aider à localiser et à résoudre rapidement d'éventuels problèmes dans divers codes, et à améliorer la couverture et la précision du code de test.

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:
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