>  기사  >  백엔드 개발  >  조롱하러 가세요

조롱하러 가세요

WBOY
WBOY원래의
2024-07-31 09:16:32709검색

Go mock

Go mock이란 무엇입니까?

Go mock은 개발자가 인터페이스에 대한 모의 구조체를 만들고 해당 동작을 정의할 수 있는 모의 프레임워크입니다.

예를 들어 Reponsitory에 대한 모의 구현을 생성하고 특정 입력을 기반으로 예상 출력을 정의하는 데 도움이 될 수 있습니다.

원본 저장소: https://github.com/golang/mock

이제 더 이상 유지 관리되지 않으므로 대신 https://github.com/uber-go/mock을 사용해야 합니다.

설치

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

주요 기능

  • 모의 생성: gomock에는 인터페이스의 모의 구현을 자동으로 생성하는 mockgen이라는 도구가 포함되어 있습니다.
  • 유연한 기대: gomock을 사용하면 다음과 같이 모의 객체의 동작에 대한 정확한 기대를 정의할 수 있습니다.
    • 수신해야 하는 인수
    • 그리고 반환해야 하는 값
    • 메서드를 호출해야 하는 특정 횟수, 최소 또는 최대 횟수

목겐 명령

mockgen CLI 사용 방법을 이해하려면 이 문서를 따르세요.

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

용법

몇 가지 메소드가 포함된 IUserRepo 인터페이스가 있다고 가정해 보겠습니다.

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. mockgen을 실행하여 모의 인스턴스 생성

go run go.uber.org/mock/mockgen@latest -source=interface.go -destination=mock.go -package=user
  • 소스: 저장소 인터페이스가 포함된 파일을 지정합니다.
  • 대상: 생성된 모의 코드가 작성될 파일을 지정합니다.
  • package: 생성된 모의 패키지 이름을 지정합니다.

2. 기대 사항 명시

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

위 테스트 파일에서:

  • specifyFunctionCalls를 사용하면 어떤 함수를 호출해야 하는지, 이러한 함수를 몇 번 호출해야 하는지 등 모의 함수 기대치를 사용자 정의할 수 있습니다.
  • specfunctionCalls 사양에 중복 함수를 추가하려고 하면(예: 첫 번째 테스트에 mockRepo.EXPECT().Update(....) 추가) 다음 오류로 인해 테스트가 실패합니다. 호출 누락 .
  • 서비스 호출이 지정되지 않은 함수인 경우 오류로 인해 테스트가 실패합니다. 해당 수신기에 대해 예상되는 "Insert" 메서드 호출이 없습니다.

소스 코드

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

위 내용은 조롱하러 가세요의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.