Golang 기능 테스트에서는 서로 다른 테스트 간의 간섭을 피하기 위해 격리가 중요합니다. 하위 테이블을 사용하여 전역 변수를 격리하거나 모의 개체를 사용하여 외부 종속성을 시뮬레이션하여 격리 문제를 해결합니다. 구체적인 단계는 다음과 같습니다. 1. 하위 테이블: 간섭을 피하기 위해 독립 변수 인스턴스를 만듭니다. 2. 모의: 외부 종속성을 격리하기 위해 모의 종속성 대체 기능을 만듭니다.
Golang 기능 테스트의 격리 문제
문제 이해
Golang 기능 테스트에서 격리는 매우 중요한 개념입니다. 격리하지 않으면 테스트가 서로 간섭하여 신뢰할 수 없는 결과를 초래할 수 있습니다.
문제 원인: 전역 변수 및 상태
전역 변수 및 상태는 격리 문제의 일반적인 원인입니다. 여러 테스트가 동일한 전역 변수에서 작동하는 경우 서로 덮어쓰여 예기치 않은 동작이 발생할 수 있습니다.
해결책: 하위 테이블과 모의 테이블을 사용하세요
격리 문제를 해결하기 위해 하위 테이블과 모의 테이블이라는 두 가지 일반적인 전략이 있습니다.
Subtables
하위 테이블은 각 테스트에 대해 고유한 변수 인스턴스를 생성하여 전역 변수를 격리합니다. 이는 다음과 같이 달성할 수 있습니다:
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) } }) }
이 예에서 각 테스트 사례에는 counter
변수의 자체 인스턴스가 있으므로 둘 사이의 간섭을 피할 수 있습니다. 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) } }rrreee🎜이 예에서
DatabaseMock
은 Database
인터페이스의 대체 요소로, 실제 데이터베이스에 대한 종속성을 격리하기 위해 해당 동작을 시뮬레이션할 수 있습니다. 🎜🎜🎜실제 예🎜🎜🎜이메일을 보내는 다음 함수를 고려하세요. 🎜rrreee🎜실제로 이메일을 보내지 않고 이 기능을 테스트하려면 모의 개체를 사용하여 mail.Dialer
를 시뮬레이션할 수 있습니다. 🎜아아아아위 내용은 Golang 기능 테스트의 격리 문제의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!