Go言語の mockgen で簡単に mock を揃える方法
Go 言語では go generate というプログラムコードを生成するための仕組みがあります。
いきなり、チューリング完全について出てきて、は? となりますが、言いたいことは、yacc や protocol buffer, go test でも、コードを解釈してコードを生成することがプログラミング言語において重要になるということのようです。 (Make でもできますが、Go言語としてインテグレーションされているのが大切だということなのでしょう)
go generate については、すでに様々な記事があるので、DRY するとして、
ポイントとしては、「コードを生成してくれる Go 標準の枠組み」ということです。
mockgen をまだ打っているの?
Go言語の標準の mockgen を利用するとき、多くの人は下記のコマンドを実行していると思います。
mockgen -source program.go -destination mock_program.go
しかし、「コードを生成してくれる Go 標準の枠組み」 である go generate を利用すると、
//go:generate mockgen -source=$GOFILE -destination=mock_$GOFILE -package=$GOPACKAGE
package fitbitauth
// Factory : Creates objects in this package
type Factory interface {
FileStore() (Store, error)
FitbitAuthHandler(fap *FitbitAuthParams, ftp *FitbitTokenParams) FitbitAuthHandler
}
Go-zen-chu/gae-fitbit-go/pkg/domain/fitbit.go
と一行目に go:generate の記述をして、あとは、go generate するだけで、mock を作成してくれます。
このとき、$GOFILE でこのファイルの名前を利用し、$GOPACKAGE でパッケージ名を利用することで、同一パッケージ、mock_ファイル名のモックを作成できます。
すると、gae-fitbit-go/pkg/domain/fitbitauth のように、mock ファイルを同一フォルダに生成できるので、大変便利です。
make ファイルで mockgen をされていた方は、ぜひ利用してみてください。
(2019/07/29 更新)go mod を利用したリポジトリで mockgen をしたら、source の package も import されてしまう
go mod により GOPATH/src/github.com/… で開発する必要が必ずしもなくなったのですが、その影響で mockgen が自身のパッケージを認識でない問題が発生しました。
mockgen source mode does not work with go1.11 modules · Issue #230 · golang/mock
self_package というオプションに、自身の GOPACKAGE を記述することにより、その package の import を封じることができます。
//go:generate mockgen -source=$GOFILE -destination=mock_$GOFILE -package=$GOPACKAGE -self_package=github.com/go-zen-chu/pkg/domain/$GOPACKAGE
package fitbitauth
これまで全く mockgen コマンドを実行すればよかったのに、これだと辛いですね…