Goでモックを使う時のメモ

2023/10/09に公開

まえがき

Goでモックを使ったテストをしようとすると毎回、モックの使い方や悩みポイントがあるのでメモを残す

環境

  • OS MacOS Sonoma
  • Go 1.21
  • moq v0.3.2
  • go-sqlmock v1.5.0
  • gorm v1.25.4

moqの使い方

コマンドラインから

# moq -out [自動生成されるモックのファイル名] [自動生成ファイルの格納場所] [モックするインターフェース名]
moq -out hoge_mock.go . hogeinterface

go generateを使用する

  1. インターフェースの実装されているファイル内に//go generate ~を書く
  2. プロジェクトのルートディレクトリで以下のコマンドを実行する

プロジェクトのルートディレクトリ : go.modファイルがあるディレクトリ

go generate ./...
//go:generate moq -out inputport_mock.go . InputPort
type InputPort interface {
    GetAll() (domain.Entities, error)
    GetById(id domain.UserID) (domain.Entity, error)
    Create(domain.CreateJson) error
    Update(id domain.UserID,param domain.CreateJson) error
    Delete(id domain.UserID) error
}

gorm + moq + sqlmockの使い方

  1. *gorm.DBをモックする
func GetNewDbMock() (*gorm.DB, sqlmock.Sqlmock, error) {
    db, mock, err := sqlmock.New()
    if err != nil {
        return nil, mock, err
    }

    gormDB, err := gorm.Open(mysql.New(mysql.Config{
        Conn: db,
        SkipInitializeWithVersion: true,
    }), &gorm.Config{})

    if err != nil {
        return gormDB, mock, err
    }
    return gormDB, mock, err
}
  1. モックした*gorm.DBを使用して、テストコードを書く
    // *gorm,DBのモックを生成
    db, mockdb, err := mock.GetNewDbMock()
    if err != nil {
        log.Fatal(err)
    }

    suuid1 := uuid.New().String()
    suuid2 := uuid.New().String()

    // クエリが実行された後の結果を設定
    rows := mockdb.NewRows([]string{"id","userid","username"}).
                    AddRow(1,suuid1,"testuser1").
                    AddRow(2,suuid2,"testuser2")

    // テスト対象関数からの呼び出しが期待されるクエリを指定して呼び出された後の結果を設定する
    mockdb.ExpectQuery(regexp.QuoteMeta("SELECT * FROM `user`")).WillReturnRows(rows)

    // テスト対象関数を呼び出す
    driver := NewDBdriver(db)
    users, err := driver.GetAll()
    expected := repository.RepositoryJsons{
        {Id: 1,Userid: suuid1,Username: "testuser1"},
        {Id: 2,Userid: suuid2,Username: "testuser2"},
    }
    assert.Equal(t , users, expected)

まとめ

毎回、モックやDBのテストしようとする時に忘れてしまうのでメモとして残しておく。
moqgo generateの使い方、頻度少ないから覚えられない。

Discussion