Heim >Backend-Entwicklung >Golang >Refactoring-Tipps für das Testen von Go-Funktionseinheiten

Refactoring-Tipps für das Testen von Go-Funktionseinheiten

WBOY
WBOYOriginal
2024-05-04 13:04:30716Durchsuche

Um die Wartbarkeit und Lesbarkeit von Go-Funktionskomponententests zu verbessern, können wir: Assertionsfunktionen extrahieren, um den Code zu vereinfachen. Verwenden Sie tabellengesteuerte Tests, um Testdaten zu organisieren. Schreiben Sie Spottschnittstellen, um die Interaktion zwischen Funktionen und Komponenten zu testen. Führen Sie detaillierte Tests durch, um Probleme zu isolieren und zu beheben. Wenden Sie Abdeckungstools an, um die Vollständigkeit der Tests sicherzustellen und Verbesserungen anzuleiten.

Go 函数单元测试的重构技巧

Refactoring-Tipps für funktionale Go-Unit-Tests

Wenn wir ein großes und komplexes Go-Projekt haben, kann die Wartung und Lesbarkeit von funktionalen Unit-Tests zu einer großen Herausforderung werden. Um dieser Herausforderung zu begegnen, können wir einige Refactoring-Techniken implementieren, um die Wartbarkeit und Lesbarkeit unserer Tests zu verbessern.

1. Behauptungsfunktion extrahieren

Wenn der Testcode viele identische Behauptungen enthält, können Sie die Behauptungsfunktion extrahieren, um den Code zu vereinfachen. Beispielsweise können wir eine AssertEqual-Funktion definieren, um zu prüfen, ob zwei Werte gleich sind: AssertEqual 函数来检查两个值是否相等:

import "testing"

func AssertEqual(t *testing.T, expected, actual interface{}) {
    if expected != actual {
        t.Errorf("Expected %v, got %v", expected, actual)
    }
}

2. 使用表驱动的测试

表驱动的测试可以帮助组织和简化测试数据。它允许我们使用一个表来提供不同的输入和期望输出,然后对每个输入执行测试。例如,我们可以编写一个表驱动的测试来检查 Max 函数:

import (
    "testing"

    "github.com/stretchr/testify/assert"
)

func TestMax(t *testing.T) {
    tests := []struct {
        name    string
        input   []int
        expected int
    }{
        {"Empty slice", []int{}, 0},
        {"Single element", []int{1}, 1},
        {"Multiple elements", []int{1, 2, 3}, 3},
    }

    for _, tt := range tests {
        actual := Max(tt.input)
        assert.Equal(t, tt.expected, actual)
    }
}

3. 编写 mocking 接口

mocking 接口允许我们测试函数在与其他组件交互时的行为。我们可以使用一个 mocking 框架(如 mockery)来生成 mock 对象,该对象实现了我们关心的接口,但我们可以控制其行为。例如,我们可以编写一个 mockDatabase 来测试一个使用数据库的函数:

package main

import (
    "database/sql"
    "fmt"
    "time"

    "github.com/stretchr/testify/mock"
)

// MockDatabase is a mock database for testing purposes.
type MockDatabase struct {
    mock.Mock
}

// Query implements the Query method of a mock database.
func (m *MockDatabase) Query(query string, args ...interface{}) (*sql.Rows, error) {
    ret := m.Called(query, args)
    return ret.Get(0).(*sql.Rows), ret.Error(1)
}

// GetUserByUsernameAndPassword implements the GetUserByUsernameAndPassword method of a mock database.
func (m *MockDatabase) GetUserByUsernameAndPassword(username, password string) (*User, error) {
    ret := m.Called(username, password)
    return ret.Get(0).(*User), ret.Error(1)
}

// User represents a user in the database.
type User struct {
    Username string
    Password string
    LastLogin time.Time
}

// main is the entry point for the program.
func main() {
    mockDB := &MockDatabase{}
    mockDB.On("GetUserByUsernameAndPassword", "john", "password").Return(&User{
        Username: "john",
        Password: "password",
        LastLogin: time.Now(),
    }, nil)

    user, err := GetUser(mockDB, "john", "password")
    if err != nil {
        fmt.Println("Error getting user:", err)
    } else {
        fmt.Println("Welcome back, ", user.Username)
    }
}

4. 运行细粒度的测试

细粒度的测试专注于测试函数的小部分功能。通过运行细粒度的测试,我们可以更轻松地隔离和调试问题。例如,我们可以编写一个测试来检查 Max

import "testing"

func TestMaxElement(t *testing.T) {
    tests := []struct {
        name    string
        input   []int
        expected int
    }{
        {"Empty slice", []int{}, 0},
        {"Single element", []int{1}, 1},
        {"Multiple elements", []int{1, 2, 3}, 3},
    }

    for _, tt := range tests {
        actual := MaxElement(tt.input)
        assert.Equal(t, tt.expected, actual)
    }
}

2 Tabellengesteuertes Testen verwenden

Tabellengesteuertes Testen kann dabei helfen, Testdaten zu organisieren und zu vereinfachen. Es ermöglicht uns, eine Tabelle zu verwenden, um verschiedene Eingaben und gewünschte Ausgaben bereitzustellen und dann Tests für jede Eingabe durchzuführen. Zum Beispiel können wir einen tabellengesteuerten Test schreiben, um die Funktion Max zu überprüfen:

rrreee

3. Schreiben Sie eine Mocking-Schnittstelle

Die Mocking-Schnittstelle ermöglicht es uns, das Verhalten einer Funktion bei der Interaktion mit zu testen andere Komponenten. Wir können ein Spott-Framework (z. B. mockery) verwenden, um Scheinobjekte zu generieren, die die Schnittstelle implementieren, die uns wichtig ist, deren Verhalten wir jedoch steuern können. Zum Beispiel können wir eine mockDatabase schreiben, um eine Funktion zu testen, die eine Datenbank verwendet:

rrreee

4. Führen Sie feinkörnige Tests aus. 🎜🎜Feinkörnige Tests konzentrieren sich auf das Testen eines kleinen Teils der Funktionalität von die Funktion. Durch die Durchführung feinkörniger Tests können wir Probleme einfacher isolieren und debuggen. Beispielsweise können wir einen Test schreiben, um zu überprüfen, ob die Funktion Max das maximale Element zurückgibt: 🎜rrreee🎜 5. Verwendung von Coverage-Tools 🎜🎜Coverage-Tools können uns dabei helfen, herauszufinden, welche Codezeilen von Tests abgedeckt werden . Dadurch können wir sicherstellen, dass unsere Testsuite umfassend ist, und können uns dabei helfen, zusätzliche Tests zu schreiben, um fehlenden Code abzudecken. 🎜🎜Fazit🎜🎜Durch die Übernahme dieser Refactoring-Techniken können wir die Wartbarkeit und Lesbarkeit von Funktions-Unit-Tests in Go-Projekten verbessern. Durch das Extrahieren von Assertionsfunktionen, die Verwendung tabellengesteuerter Tests, das Schreiben von Spottschnittstellen, das Ausführen feinkörniger Tests und die Verwendung von Abdeckungstools können wir zuverlässigeren und wartbareren Testcode schreiben. 🎜

Das obige ist der detaillierte Inhalt vonRefactoring-Tipps für das Testen von Go-Funktionseinheiten. 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