Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Pergi mengejek

Pergi mengejek

WBOY
WBOYasal
2024-07-31 09:16:32609semak imbas

Go mock

Apa itu Go mock

Go mock ialah rangka kerja olok-olok yang membolehkan pembangun mencipta struktur olok-olok untuk antara muka kami dan menentukan tingkah laku mereka.

Sebagai contoh, ini boleh membantu kami menjana pelaksana olok-olok untuk Reponsitory dan mentakrifkan output yang dijangkakan berdasarkan input tertentu.

Repo asal: https://github.com/golang/mock

Kini ia tidak lagi diselenggara, jadi kita harus menggunakan https://github.com/uber-go/mock sebaliknya.

Pemasangan

go install go.uber.org/mock/mockgen@latest

Ciri-ciri utama

  • Generasi Mock: gomock menyertakan alat yang dipanggil mockgen yang secara automatik menjana pelaksanaan olok-olok antara muka.
  • Jangkaan Fleksibel: Dengan gomock, anda boleh menentukan jangkaan tepat pada gelagat objek olok-olok, seperti:
    • Hujah yang sepatutnya diterima
    • Dan nilai yang sepatutnya dikembalikan
    • Bilangan tertentu, min atau bilangan maksimum kali kaedah harus dipanggil

Perintah Mockgen

Ikuti dokumen ini untuk memahami cara menggunakan mockgen CLI:

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

Penggunaan

Andaikan anda mempunyai antara muka IUserRepo dengan beberapa kaedah:

ports.go

package user

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

domain.go

package user

type User struct {
    ID   int
    Name string
}

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

1. Jalankan mockgen untuk menjana instnace olok-olok

go run go.uber.org/mock/mockgen@latest -source=interface.go -destination=mock.go -package=user
  • sumber: Menentukan fail yang mengandungi antara muka Repositori.
  • destinasi: Menentukan fail tempat kod olok-olok yang dihasilkan akan ditulis.
  • pakej: Menentukan nama pakej untuk mock yang dijana.

2. Nyatakan Jangkaan

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

Dalam fail ujian di atas:

  • specifyFunctionCalls membolehkan kami menyesuaikan jangkaan fungsi olok-olok, fungsi mana yang mesti dipanggil dan berapa kali fungsi ini mesti dipanggil.
  • Jika anda cuba menambah fungsi redundan ke dalam spesifikasi specifyFunctionCalls (cth. menambahkan mockRepo.EXPECT().Kemas kini(....) dalam ujian pertama), ujian anda akan gagal disebabkan ralat: panggilan hilang .
  • Jika perkhidmatan anda memanggil fungsi yang belum ditentukan, ujian anda akan gagal kerana ralat: tiada panggilan dijangka kaedah "Sisipkan" untuk penerima itu.

Kod sumber

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

Atas ialah kandungan terperinci Pergi mengejek. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Artikel sebelumnya:Ujian Unit Di PergiArtikel seterusnya:Ujian Unit Di Pergi