go:極簡上手使用 stretchr/testify 進行mock測試

superpigwin發表於2024-10-21

庫安裝

首先,安裝 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)
}

說明

  1. GetterTestSuite 是測試集的名稱,每個method都會作為測試用例呼叫。TestGetter 函式執行時,會呼叫 TestGetterInt
  2. TestGetterInt 中引用的 tTestSuite,包含許多有用的斷言函式,如 EqualNil 等。
  3. 建立 Mock 例項後,可以使用 On 方法來標記方法對應的返回值。假設 Get 方法可以傳遞引數,則可以根據不同的引數選擇不同的返回值。

Mock 常見用法

假設 mockObj 是 Mock 類的例項:

  1. mockObj.On("GetApiKey", mock.Anything).Return("dummy_api_key")GetApiKey 有一個引數,且無論傳什麼,都會返回 dummy_api_key
  2. mockObj.On("GetAllClusterInfo").Maybe().Return(GenerateTestClustersInfo()):如果使用 Maybe,則 GetAllClusterInfo 不一定必須被呼叫;如未使用 Maybe 且函式未被呼叫,則斷言將失敗。
  3. mockObj.On("RunCleanup", true, true).Once().Return(nil, nil)RunCleanup 有兩個引數,所以需要傳遞兩個 Mock 的值進入。Once 表示這個函式只應該被呼叫一次。
  4. mockObj.AssertNumberOfCalls(t.T(), "RunCleanup", 4):可以檢查方法的呼叫次數。

透過這些用法,使用者可以完全控制 Mock 類的每個方法的行為,並進行一些檢查以完善整個測試。

相關文章