テストダブル:モックとスタブ
テスト容易性と依存性注入のためのインターフェース
「テストダブル:モックとスタブ」はCoddyKit上の無料Go Academyレッスンです。 これはレッスン3/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはGo Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Go Academyコースには全4レッスンが含まれています。
テストダブルの概要
テストダブルは、テスト内で実際の依存先を置き換えるものです。種類には、stub(あらかじめ用意した応答を返す)、mock(操作を検証する)、spy(呼び出しを記録する)、fake(動作するインメモリ実装)があります。
インターフェースでテストダブルを利用する
具象型ではなく、インターフェースを受け取るように関数を設計してください。本番環境では実際の実装を渡し、テストではテストダブルを渡します。
type UserStore interface {
FindByID(id int) (*User, error)
}
func GetUser(store UserStore, id int) (*User, error) {
return store.FindByID(id)
}手動スタブ
スタブは、インターフェースを実装して設定済みの値を返す単純な構造体です:
type stubStore struct{ user *User; err error }
func (s *stubStore) FindByID(_ int) (*User, error) { return s.user, s.err }
// In test:
store := &stubStore{user: &User{Name: "Alice"}}
result, _ := GetUser(store, 1)手動モック
モックは呼び出しを記録し、その内容を検証します:
type mockStore struct {
called bool
gotID int
user *User
}
func (m *mockStore) FindByID(id int) (*User, error) {
m.called = true; m.gotID = id
return m.user, nil
}
// Assert: if !mock.called { t.Error(...) }testify/mock
testify/mock パッケージは、呼び出しの期待値と返り値の設定を備えたモックオブジェクトを生成または記述するための機能を提供します:
type MockStore struct { mock.Mock }
func (m *MockStore) FindByID(id int) (*User, error) {
args := m.Called(id)
return args.Get(0).(*User), args.Error(1)
}
// In test:
m := new(MockStore)
m.On("FindByID", 1).Return(&User{}, nil)
m.AssertExpectations(t)gomock
go.uber.org/mock/gomock(以前の golang/mock)は、インターフェースからモックを生成します。生成には mockgen CLI を使用し、期待値の設定には EXPECT() を使用します。
Fake
フェイクは、動作するインメモリ実装です。たとえば、ユーザーをマップに保存するインメモリのユーザーストアがあります。フェイクは作成に手間がかかりますが、モックよりも現実に近く、実装の変更にも影響されにくいという利点があります。
type fakeStore struct{ users map[int]*User }
func (f *fakeStore) FindByID(id int) (*User, error) {
u, ok := f.users[id]
if !ok { return nil, ErrNotFound }
return u, nil
}HTTP クライアント向け httptest
net/http/httptest は、プロセス内で動作する HTTP テストサーバーとレコーダーを提供します。HTTP ベースの依存先に対する標準的なフェイクです。
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
json.NewEncoder(w).Encode(User{Name: "Alice"})
}))
defer ts.Close()各テストダブルを使う場面
スタブ:単純な固定レスポンス。モック:呼び出し回数や引数の検証。フェイク:複雑な動作。モックを使いすぎないでください。統合テストでは、フェイクや実際のコンポーネントのほうが信頼性が高くなります。
壊れやすいテストを避ける
呼び出し順や引数の値を厳密に検証するモックは、実装の進化に伴って壊れやすくなります。可能な場合は、出力を検証するスタブやフェイクを優先してください。
インターフェースの抽出
呼び出し側が使用する具象型の表面を特定してから、インターフェースを抽出します(ISP)。Go は暗黙的なインターフェース実装に対応しているため、具象型を変更する必要はありません。
クイックチェック
スタブとモックの主な違いは何ですか?
振り返り:テストダブル
主なポイント:
- テストダブルを利用できるよう、インターフェースに対して設計する
- スタブ:あらかじめ用意したデータを返す。モック:操作を検証する
- HTTP には httptest、ストレージにはインメモリのフェイクを使う
- モックを使いすぎず、複雑な動作にはフェイクを優先する
よくある質問
「テストダブル:モックとスタブ」レッスンは無料ですか?
はい。「テストダブル:モックとスタブ」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Go Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Go Academyコースには全4レッスンが含まれています。
「テストダブル:モックとスタブ」で何を学びますか?
テスト容易性と依存性注入のためのインターフェース ブラウザで直接実行するハンズオンコードでGo Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Go Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのGo Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン3/4です。
「テストダブル:モックとスタブ」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このGo Academyレッスンでコードを書いて実行できますか?
はい。すべてのGo Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- testingによるユニットテストの作成
- テーブル駆動テスト
- テストダブル:モックとスタブ
- テストカバレッジとtestify