Dans les tests de fonction Golang, l'isolement est crucial pour éviter les interférences entre les différents tests. Résolvez le problème d'isolation en isolant les variables globales à l'aide de sous-tableaux ou en simulant des dépendances externes à l'aide d'objets fictifs. Les étapes spécifiques sont les suivantes : 1. Sous-table : créer des instances de variables indépendantes pour éviter les interférences ; 2. Mock : créer des substituts de dépendance fictifs pour isoler les dépendances externes.
Problèmes d'isolement dans les tests de fonction Golang
Comprendre les problèmes
Dans les tests de fonction Golang, l'isolement est un concept très important. Sans isolement, les tests peuvent interférer les uns avec les autres, conduisant à des résultats peu fiables.
Source du problème : variables globales et état
Les variables globales et l'état sont une cause fréquente de problèmes d'isolement. Si plusieurs tests fonctionnent sur la même variable globale, ils peuvent s'écraser mutuellement, provoquant un comportement inattendu.
Solution : utiliser des sous-tables et des simulations
Pour résoudre le problème d'isolement, il existe deux stratégies courantes : les sous-tables et les simulations.
Sous-tables
Les sous-tables isolent les variables globales en créant leur propre instance de la variable pour chaque test. Ceci peut être réalisé par :
package mypkg // Global variable (not thread-safe) var counter int func Increment() int { counter++ return counter }
package mypkg_test import ( "testing" ) func TestIncrement(t *testing.T) { // Create a sub-table for each test case t.Run("first call", func(t *testing.T) { // Initialize a new table-local counter counter := 0 // Call the Increment function and assert the result result := mypkg.Increment() if result != 1 { t.Errorf("Expected 1, got %d", result) } }) t.Run("second call", func(t *testing.T) { // Initialize a new table-local counter counter := 0 // Call the Increment function and assert the result result := mypkg.Increment() if result != 2 { t.Errorf("Expected 2, got %d", result) } }) }
Dans cet exemple, chaque scénario de test a sa propre instance de la variable counter
, évitant ainsi les interférences entre eux. counter
变量实例,从而避免了它们之间的干扰。
mock
mock 对象是模拟函数的替身,可以用来隔离外部依赖项。这对于测试依赖于外部服务或数据库的函数非常有用。
package mypkg type Database interface { // ... }
package mypkg_test import ( "testing" "github.com/stretchr/testify/mock" ) type DatabaseMock struct { mock.Mock } // ... func TestMyFunction(t *testing.T) { // Create a mock database mockDB := &DatabaseMock{} // Setup mock expectations mockDB.On("Query", ...).Return(...) // Call the function under test with the mock database mypkg.MyFunction(mockDB) // Assert that the mock expectations were met mockDB.AssertExpectations(t) }
在这个例子中,DatabaseMock
是 Database
接口的替身,允许我们模拟其行为以隔离对实际数据库的依赖。
实战案例
考虑下面的函数,它发送电子邮件:
package email import ( "github.com/go-mail/mail" ) func SendEmail(smtpHost, smtpPort, senderEmail, senderPassword, recipientEmail, subject, body string) error { mail := mail.NewMessage() // ... smtpDialer := mail.NewDialer(smtpHost, smtpPort, senderEmail, senderPassword) return smtpDialer.DialAndSend(mail) }
要测试此函数而不实际发送电子邮件,我们可以使用 mock 对象来模拟 mail.Dialer
package email_test import ( "testing" email "github.com/my-username/my-email-package" "github.com/stretchr/testify/mock" ) type DialerMock struct { mock.Mock } func (d *DialerMock) DialAndSend(mail *mail.Message) error { d.Called(mail) return nil } func TestSendEmail(t *testing.T) { // Create a mock dialer mockDialer := &DialerMock{} // Setup mock expectations mockDialer.On("DialAndSend", ...).Return(nil) // Call the function under test with the mock dialer result := email.SendEmail("", "", "", "", "", "", "") // Assert that mock expectations were met mockDialer.AssertExpectations(t) // Assert the result of the function under test if result != nil { t.Errorf("Expected nil error but got %v", result) } }
DatabaseMock
est un remplaçant de l'interface Database
, nous permettant de simuler son comportement pour isoler la dépendance à la base de données réelle. 🎜🎜🎜Exemple pratique🎜🎜🎜Considérez la fonction suivante, qui envoie un e-mail : 🎜rrreee🎜Pour tester cette fonction sans réellement envoyer d'e-mail, nous pouvons utiliser un objet fictif pour simuler mail.Dialer
: 🎜rrreeeCe 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!