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