Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Tests in Go

Tests in Go

Yunosuke Yamada

October 16, 2022
Tweet

More Decks by Yunosuke Yamada

Other Decks in Programming

Transcript

  1. type Repository interface { FindAllTodos() ([]Todo, error) } type repository

    struct { db *sql.DB } func (r repository) FindAllTodos() ([]Todo, error) { ... } // 返り値が Repository にできている func NewRepository(db *sql.DB) Repository { return repository{db} } 5
  2. DB アクセスを Repository へ移譲する type UseCase interface { GetTodos() ([]Todo,

    error) } type useCase struct { repoitory Repository } func NewTodoUseCase(repoitory Repository) UseCase { return useCase{ repoitory, } } func (u useCase) GetTodos() ([]Todo, error) { return u.repoitory.FindAllTodos() } 7
  3. mock を使ったテスト func TestGetTodos(t *testing.T) { mockRet := []model.Todo{{ID: 1,

    Content: "Todo1"}} // mock 生成 ctrl := gomock.NewController(t) defer ctrl.Finish() mock := mock_repository.NewMockRepository(ctrl) // 期待する振る舞いを設定 mock.EXPECT().FindAllTodos().Return(mockRet, nil) // 注入 usecase := NewUseCase(mock) actual, _ := usecase.GetTodos() assert.Equal(t, mockRet, actual) } 9
  4. DB のテスト Go に限った話ではないがいくつか方法がある mock を使う方法 比較的簡単だが、DB を使ったときに本当に動くかは分からない。 ORM を使う場合は生成される

    SQL を再現しないといけないかも。 軽量な DB を使う(割愛) 実際の DB を使う方法 mock の逆で、初期化と後処理の方法を考える必要がある。 11
  5. func TestCreateTodo(t *testing.T) { txdb.Register("find_all_todos", "mysql", "dsn") db, _ :=

    sql.Open("find_all_todos", "dsn") defer db.Close() // 最後に閉じてロールバック repo := NewRepository(db) actual, _ := repo.CreateTodo("todo4") assert.Equal(t, &model.Todo{ID: 4, Content: "todo4"}, actual) todos, _ := repo.FindAllTodos() assert.Equal(t, 4, len(todos)) } 13