庫安裝
首先,安裝 Mock 類生成工具 Mockery:
go install github.com/vektra/mockery/v2@v2.45.1
實際上,你也可以手動建立 Mock 類。
生成 Mock 類
假設你在 internal/metrics
包下有如下定義的介面:
package metrics
type Getter[T any] interface {
Get() (T, error)
}
在專案根目錄,可以使用以下命令生成 Mock 類:
mockery --name=Getter --dir=internal/metrics
生成的 Mock 類會在 mocks
目錄下的 getter.go
檔案中。
編寫用例
package metrics
import (
"testing"
mocks "xxx/mock/internal_/metrics"
"github.com/stretchr/testify/suite"
)
type GetterTestSuite struct {
suite.Suite
}
func TestGetter(t *testing.T) {
suite.Run(t, new(GetterTestSuite))
}
func (t *GetterTestSuite) TestGetterInt() {
t.T().Logf("TestGetterInt run")
getter := new(mocks.Getter[int])
getter.On("Get").Return(1, nil)
val, err := getter.Get()
t.Nil(err)
t.Equal(1, val)
}
說明:
- GetterTestSuite 是測試集的名稱,每個method都會作為測試用例呼叫。TestGetter 函式執行時,會呼叫 TestGetterInt。
- TestGetterInt 中引用的
t
是TestSuite
,包含許多有用的斷言函式,如Equal
和Nil
等。 - 建立 Mock 例項後,可以使用
On
方法來標記方法對應的返回值。假設Get
方法可以傳遞引數,則可以根據不同的引數選擇不同的返回值。
Mock 常見用法:
假設 mockObj
是 Mock 類的例項:
mockObj.On("GetApiKey", mock.Anything).Return("dummy_api_key")
:GetApiKey
有一個引數,且無論傳什麼,都會返回dummy_api_key
。mockObj.On("GetAllClusterInfo").Maybe().Return(GenerateTestClustersInfo())
:如果使用Maybe
,則GetAllClusterInfo
不一定必須被呼叫;如未使用Maybe
且函式未被呼叫,則斷言將失敗。mockObj.On("RunCleanup", true, true).Once().Return(nil, nil)
:RunCleanup
有兩個引數,所以需要傳遞兩個 Mock 的值進入。Once
表示這個函式只應該被呼叫一次。mockObj.AssertNumberOfCalls(t.T(), "RunCleanup", 4)
:可以檢查方法的呼叫次數。
透過這些用法,使用者可以完全控制 Mock 類的每個方法的行為,並進行一些檢查以完善整個測試。