0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

GoMock入門:初心者向けの使い方とテストの書き方

Posted at

はじめに

GoMockは、Go言語でモック(Mock)を使ったテストを簡単に書けるようにするライブラリです。
外部APIやデータベースに依存するコードをテストする際、GoMockを使うことで依存関係を分離し、効率的なユニットテストが実現できます。

本記事では、GoMockの基本的な使い方を中心に、以下の内容を解説します。

対象読者

  • Go言語のテストを学び始めた方
  • 外部APIやDBに依存しないテストを書きたい方
  • GoMockを使ってモックを作成したい方

目次

  1. GoMockとは?
  2. インストール方法
  3. 基本的な使い方
    • モックの生成
    • モックの設定
    • モックの検証
  4. 実践:GoMockを使ったユニットテスト

1. そもそもGoMockとは?

GoMockは、Go言語用のモック生成ライブラリで、以下の特徴があります。

  • 依存関係を分離して、テスト対象の関数やメソッドだけを検証できる。
  • gomock.Controllerを使って、モックの動作を設定・検証できる。
  • Mockgenというツールを使って、インターフェースからモックコードを自動生成 できる。

2. インストール方法

1. GoMockとMockgenのインストール
以下のコマンドを実行して、GoMockとMockgenをインストールします。

go install github.com/golang/mock/mockgen@latest

.zshrcまたは.bash_profileに以下を追加して、環境変数PATHを設定します。

export PATH=$PATH:$(go env GOPATH)/bin

設定を反映させるために、以下を実行します。

source ~/.zshrc  # Zshを使用している場合
source ~/.bash_profile  # Bashを使用している場合

2. Go Modulesに追加
go.modにGoMockを追加します。

go get github.com/golang/mock/gomock

3. 基本的な使い方

3.1 モックの生成
Mockgenを使って、インターフェースからモックを自動生成します。
今回は、UserRepositoryインターフェースをモック化してみます。

user.go

package example

type User struct {
    ID   int
    Name string
}

type UserRepository interface {
    GetUser(id int) (*User, error)
}

以下のコマンドを実行して、モックを生成します。

mockgen -source=user.go -destination=mock_user.go -package=example
  • -source: モックを生成する元のインターフェースを含むファイル
  • -destination: 生成されるモックのファイル名
  • -package: モックを含むパッケージ名

3.2 モックの設定
gomock.Controllerを使って、モックの動作を設定します。

user_test.go

package example_test

import (
    "errors"
    "testing"

    "github.com/golang/mock/gomock"
    "example"
)

func TestGetUser_Success(t *testing.T) {
    ctrl := gomock.NewController(t)
    defer ctrl.Finish()

    mockRepo := example.NewMockUserRepository(ctrl)
    mockRepo.EXPECT().GetUser(1).Return(&example.User{ID: 1, Name: "John"}, nil)

    user, err := mockRepo.GetUser(1)
    if err != nil {
        t.Fatal("expected no error, but got", err)
    }
    if user.Name != "John" {
        t.Fatal("expected user name to be John, but got", user.Name)
    }
}

3.3 モックの検証

  • EXPECT()を使って、モックの動作を設定
  • Return()を使って、モックの返り値を設定
  • ctrl.Finish()で、呼び出し回数の検証 を行う

4. 実践:GoMockを使ったユニットテスト

GoMockを使って、外部依存を分離したユニットテストを実装します。
今回は、UserServiceUserRepositoryに依存しているケースをテストします。

4.1 UserServiceの実装
user_service.go

package example

import "errors"

type UserService struct {
    repo UserRepository
}

func NewUserService(repo UserRepository) *UserService {
    return &UserService{repo: repo}
}

func (s *UserService) GetUserName(id int) (string, error) {
    user, err := s.repo.GetUser(id)
    if err != nil {
        return "", err
    }
    if user == nil {
        return "", errors.New("user not found")
    }
    return user.Name, nil
}

4.2 UserServiceのテスト実装
user_service_test.go

package example_test

import (
    "errors"
    "testing"

    "github.com/golang/mock/gomock"
    "example"
)

func TestGetUserName_Success(t *testing.T) {
    ctrl := gomock.NewController(t)
    defer ctrl.Finish()

    mockRepo := example.NewMockUserRepository(ctrl)
    mockRepo.EXPECT().GetUser(1).Return(&example.User{ID: 1, Name: "John"}, nil)

    service := example.NewUserService(mockRepo)
    name, err := service.GetUserName(1)
    if err != nil {
        t.Fatal("expected no error, but got", err)
    }
    if name != "John" {
        t.Fatal("expected name to be John, but got", name)
    }
}

func TestGetUserName_NotFound(t *testing.T) {
    ctrl := gomock.NewController(t)
    defer ctrl.Finish()

    mockRepo := example.NewMockUserRepository(ctrl)
    mockRepo.EXPECT().GetUser(1).Return(nil, nil)

    service := example.NewUserService(mockRepo)
    _, err := service.GetUserName(1)
    if err == nil || err.Error() != "user not found" {
        t.Fatal("expected user not found error, but got", err)
    }
}
  • mockRepo.EXPECT()を使って、期待する動作を設定
  • テストケースとして、成功ケースとユーザーが見つからないケースを実装

まとめ

項目 説明
GoMock Go言語用のモック生成ライブラリ
Mockgen インターフェースからモックを自動生成
Controller モックの動作を設定・検証する

GoMockを使うことで、外部依存を切り離してテストできるため、高品質なユニットテストを効率的に書くことが可能になります!

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?