テスト実行
go test ./... -v
テストの流れ
各レイヤーのテストは基本的に下記の流れです。
-
mock
を作成して - テスト対象のレシーバにセットして
- テスト対象のメソッドを呼び出して
- 結果を検証する
例
t.Run("error", func(t *testing.T) {
ctrl := gomock.NewController(t)
GroupUsecase := mocks.NewMockIGroup(ctrl) -> mockを作る
GroupUsecase.EXPECT().GetTopList().Return(nil, fmt.Errorf("test")) -> mockの挙動を決定
h := &Group{
GroupUsecase: GroupUsecase, -> セットして
}
e := echo.New()
req := httptest.NewRequest(http.MethodPost, "/", nil)
rec := httptest.NewRecorder()
c := e.NewContext(req, rec)
err := h.TopList(c) -> テスト対象メソッド呼出
assert.Error(t, err) -> 結果を検証する
})
gomock, mockgen
handler
, usecase
は依存するinterfaceのmockをテスト中で実装していますが、mockはgomockを使って実装しています。
また、mockgen
という定義したinterfaceからmockを作ってくれるツールも同梱しているのでmockはそれを使って生成しています。
$ go get github.com/golang/mock/gomock
$ go install github.com/golang/mock/mockgen
interfaceを追加、修正などしたらmockgen.sh
を実行してください。
sh mockgen.sh
すると、各レイヤーのmocks
以下にmockが生成されます。
handler/mocks/
└── group.go
sqlmock
repository
レイヤーはgorm.DB
に依存しているのでgo-sqlmockを使ってgorm
が依存するdatabase/sql
のdatabase/mysql
をモックしてしまいます。
mockとは
各レイヤーはinterfaceを通じて依存しているので、interfaceを遵守するmockを代わりにセットすることで擬似的に各インスタンス呼び出しています。
mockを使うとモックDBなど用意する必要が無く原則ソースコード単体でテストを作ることができるようになります。