Golang 関数のテストでは、異なるテスト間の干渉を避けるために分離が重要です。サブテーブルを使用してグローバル変数を分離するか、モック オブジェクトを使用して外部依存関係をシミュレートすることにより、分離の問題を解決します。具体的な手順は次のとおりです。 1. サブテーブル: 独立変数インスタンスを作成して干渉を回避します。 2. モック: モック依存関係のスタンドインを作成して外部依存関係を分離します。
Golang 関数テストにおける分離の問題
問題の理解
Golang In機能テスト、分離は非常に重要な概念です。分離しないとテストが相互に干渉し、信頼性の低い結果が得られる可能性があります。
問題の原因: グローバル変数と状態
グローバル変数と状態は、分離の問題の一般的な原因です。複数のテストが同じグローバル変数に対して実行される場合、それらのテストは互いに上書きされ、予期しない動作が発生する可能性があります。
解決策: サブテーブルとモックを使用する
分離の問題を解決するには、サブテーブルとモックという 2 つの一般的な戦略があります。
サブテーブル
サブテーブルは、テストごとに変数の独自のインスタンスを作成することでグローバル変数を分離します。これは、次の方法で実現できます。
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
変数インスタンスがあるため、テスト ケース間の干渉が回避されます。
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) }
実際に電子メールを送信せずにこの関数をテストするには、次のようにします。 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) } }
以上がGolang 関数テストにおける分離の問題の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。