Heim  >  Artikel  >  Backend-Entwicklung  >  Isolationsprobleme beim Golang-Funktionstest

Isolationsprobleme beim Golang-Funktionstest

王林
王林Original
2024-04-17 09:06:01644Durchsuche

Bei Golang-Funktionstests ist die Isolation entscheidend, um Interferenzen zwischen verschiedenen Tests zu vermeiden. Lösen Sie das Isolationsproblem, indem Sie globale Variablen mithilfe von Untertabellen isolieren oder externe Abhängigkeiten mithilfe von Scheinobjekten simulieren. Die spezifischen Schritte sind: 1. Untertabelle: Erstellen Sie unabhängige Variableninstanzen, um Interferenzen zu vermeiden. 2. Mock: Erstellen Sie Scheinabhängigkeits-Stellvertreter, um externe Abhängigkeiten zu isolieren.

Golang 函数测试中的隔离问题

Isolationsprobleme beim Golang-Funktionstest

Probleme verstehen

Bei Golang-Funktionstests ist Isolation ein sehr wichtiges Konzept. Ohne Isolierung können sich Tests gegenseitig beeinflussen und zu unzuverlässigen Ergebnissen führen.

Quelle des Problems: Globale Variablen und Status

Globale Variablen und Status sind eine häufige Ursache für Isolationsprobleme. Wenn mehrere Tests mit derselben globalen Variablen arbeiten, können sie sich gegenseitig überschreiben, was zu unerwartetem Verhalten führt.

Lösung: Untertabellen und Mocks verwenden

Um das Isolationsproblem zu lösen, gibt es zwei gängige Strategien: Untertabellen und Mocks.

Untertabellen

Untertabellen isolieren globale Variablen, indem sie für jeden Test eine eigene Instanz der Variablen erstellen. Dies kann erreicht werden durch:

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)
    }
  })
}

In diesem Beispiel verfügt jeder Testfall über eine eigene Instanz der Variablen counter, wodurch Interferenzen zwischen ihnen vermieden werden. 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)
}

在这个例子中,DatabaseMockDatabase 接口的替身,允许我们模拟其行为以隔离对实际数据库的依赖。

实战案例

考虑下面的函数,它发送电子邮件:

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

🎜Mock🎜🎜🎜Mock-Objekte sind Stellvertreter für Mock-Funktionen und können zum Isolieren externer Abhängigkeiten verwendet werden. Dies ist nützlich zum Testen von Funktionen, die von externen Diensten oder Datenbanken abhängig sind. 🎜
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🎜In diesem Beispiel ist DatabaseMock ein Ersatz für die Database-Schnittstelle, der es uns ermöglicht, ihr Verhalten zu simulieren, um die Abhängigkeit von der tatsächlichen Datenbank zu isolieren. 🎜🎜🎜Praktisches Beispiel🎜🎜🎜Betrachten Sie die folgende Funktion, die eine E-Mail sendet: 🎜rrreee🎜Um diese Funktion zu testen, ohne die E-Mail tatsächlich zu senden, können wir ein Scheinobjekt verwenden, um mail.Dialer zu simulieren: 🎜rrreee

Das obige ist der detaillierte Inhalt vonIsolationsprobleme beim Golang-Funktionstest. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn