Heim > Backend-Entwicklung > Golang > Mach dich lustig

Mach dich lustig

WBOY
Freigeben: 2024-07-31 09:16:32
Original
774 Leute haben es durchsucht

Go mock

Was ist Go-Mock?

Go Mock ist ein Mocking-Framework, das es Entwicklern ermöglicht, Scheinstrukturen für unsere Schnittstellen zu erstellen und deren Verhalten zu definieren.

Zum Beispiel kann es uns helfen, die Scheinimplementierungen für Repository zu generieren und die erwartete Ausgabe basierend auf den bestimmten Eingaben zu definieren.

Original-Repo: https://github.com/golang/mock

Jetzt wird es nicht mehr gepflegt, daher sollten wir stattdessen https://github.com/uber-go/mock verwenden.

Installation

go install go.uber.org/mock/mockgen@latest
Nach dem Login kopieren

Hauptmerkmale

  • Mock-Generierung: Gomock enthält ein Tool namens Mockgen, das automatisch Scheinimplementierungen von Schnittstellen generiert.
  • Flexible Erwartungen: Mit Gomock können Sie genaue Erwartungen an das Verhalten von Scheinobjekten definieren, wie zum Beispiel:
    • Die Argumente, die es erhalten sollte
    • Und die Werte, die zurückgegeben werden sollen
    • Spezifische Häufigkeit, minimale oder maximale Häufigkeit, mit der eine Methode aufgerufen werden soll

Mockgen-Befehl

Befolgen Sie dieses Dokument, um zu verstehen, wie Sie die Mockgen-CLI verwenden:

https://github.com/uber-go/mock?tab=readme-ov-file#running-mockgen

Verwendung

Angenommen, Sie haben eine IUserRepo-Schnittstelle mit einigen Methoden:

ports.go

package user

type IUserRepo interface {
    GetUserByID(id int) (*User, error)
    Insert(user User) error
    Update(id int, user User) error
}
Nach dem Login kopieren

domain.go

package user

type User struct {
    ID   int
    Name string
}

Nach dem Login kopieren

service.go

package user

import "fmt"

type UserService struct {
    repo IUserRepo
}

var invalidUserIDError = fmt.Errorf("invalid user id")

func (u *UserService) Upsert(user User) error {
    if user.ID <= 0 {
        return invalidUserIDError
    }
    existingUser, err := u.repo.GetUserByID(user.ID)
    if err != nil {
        return err
    }
    if existingUser == nil {
        return u.repo.Insert(user)
    }

    return u.repo.Update(user.ID, user)
}

Nach dem Login kopieren

1. Führen Sie „mockgen“ aus, um eine Scheininstanz zu generieren

go run go.uber.org/mock/mockgen@latest -source=interface.go -destination=mock.go -package=user
Nach dem Login kopieren
  • Quelle: Gibt die Datei an, die die Repository-Schnittstelle enthält.
  • Ziel: Gibt die Datei an, in die der generierte Mock-Code geschrieben wird.
  • Paket: Gibt den Paketnamen für den generierten Mock an.

2. Erwartungen angeben

service_test.go

package user

import (
    "go.uber.org/mock/gomock"
    "github.com/stretchr/testify/assert"
    "testing"
)

func TestUpsertUser(t *testing.T) {
    mockCtl := gomock.NewController(t)
    defer mockCtl.Finish()

    tests := []struct {
        name                 string
        user                 User
        specifyFunctionCalls func(mock *MockIUserRepo)
        expectedError        error
    }{
        {
            user: User{ID: 1, Name: "User 1"},
            name: "Should insert",
            specifyFunctionCalls: func(mockRepo *MockIUserRepo) {
                mockRepo.EXPECT().GetUserByID(1).Return(nil, nil).Times(1)
                mockRepo.EXPECT().Insert(User{ID: 1, Name: "User 1"}).Return(nil).Times(1)
            },
        },
        {
            name: "User existed - Should update",
            user: User{ID: 1, Name: "New User Name"},
            specifyFunctionCalls: func(mockRepo *MockIUserRepo) {
                mockRepo.EXPECT().GetUserByID(1).Return(&User{ID: 1, Name: "User 1"}, nil).Times(1)
                mockRepo.EXPECT().Update(1, User{ID: 1, Name: "New User Name"}).Return(nil).Times(1)
            },
        },
        {
            expectedError: invalidUserIDError,
        },
    }

    for _, test := range tests {
        t.Run(test.name, func(t *testing.T) {
            mockRepo := NewMockIUserRepo(mockCtl)
            if test.specifyFunctionCalls != nil {
                test.specifyFunctionCalls(mockRepo)
            }
            userService := UserService{repo: mockRepo}
            err := userService.Upsert(test.user)
            assert.Equal(t, test.expectedError, err)
        })
    }
}

Nach dem Login kopieren

In der Testdatei oben:

  • Mit „specifyFunctionCalls“ können wir die Scheinfunktionserwartung anpassen, welche Funktionen aufgerufen werden müssen und wie oft diese Funktionen aufgerufen werden müssen.
  • Wenn Sie versuchen, eine redundante Funktion zur Spezifikation „specifyFunctionCalls“ hinzuzufügen (z. B. durch Hinzufügen von „mockRepo.EXPECT().Update(....)“ im ersten Test), schlägt Ihr Test aufgrund des Fehlers „fehlende(r) Aufruf(e)“ fehl. .
  • Wenn Ihr Dienst eine Funktion aufruft, die nicht angegeben wurde, schlägt Ihr Test aufgrund des Fehlers fehl: Es gibt keine erwarteten Aufrufe der Methode „Insert“ für diesen Empfänger.

Quellcode

https://github.com/huantt/gomock-demo

Das obige ist der detaillierte Inhalt vonMach dich lustig. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Quelle:dev.to
Erklärung dieser Website
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
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage