対象読者
- Go の mockgen で生成した *_mock.go ファイルのせいで Build がコケている人
- 自分
忙しい人のための結論
Build failed 時に、怒られているコード内の該当箇所を消せばよい。
事例
REST API を golang で書いていた。
テストコードを書くべく、mockgen でモックを生成したところ、それらのファイルにいちゃもんをつけられて Build が通らなくなった。
# hoge/fuga
fuga | hoge/fuga_mock.go:**:*: m.ctrl.T undefined (type *gomock.Contr
oller has no field or method T)
m.ctrl.T で怒られるのは gomock の code generation が悪いからではないかと推測される。下記リンクによると gomock の version が関係していそう。
参考:https://github.com/openshift/openshift-azure/issues/870
下記リンクによると、同様の問題(m.ctrl.T undefined)が発生したが、gomock を v1.2.0 にしたところ動いたという。原因は構造体のフィールド t の表記を T と変更したことのようだ。
https://github.com/golang/mock/issues/255
では、go get で落とした gomock, mockgen の version を変更するには?
Q. go get で落としたパッケージの version を変更する場合には?
A. $GOPATH 以下の src/ で、以下を実行し、使用するバージョン情報のブランチにチェックアウトする。
$ git tag -l #各バージョンのブランチが表示(tags/v1.2.0 など)
$ git checkout tags/v1.2.0 #v1.2.0 に切り替える場合
または glide などでパッケージ管理するといいらしい(Go version 1.5 以上)。
参考:https://qiita.com/usk81/items/8e192e68d6b18bec3b4a
だが、今回の問題に関してはより簡単な方法があった。。。
改めて結論
以下のようなメッセージが表示される箇所はコメントアウトしたところ、問題なく Build が成功した。下記の場合では、m.ctrl.T を含む行をコメントアウトした。
*****-*** | hoge/fuga_mock.go:37:8: m.ctrl.T undefined (type *gomock.Controller has no field or method T)
mockgen のバージョンを最新にすると通ったという声もある(詳細は未確認)。
余談:GOPATH が 2 つ以上指定されている場合
$GOPATH に指定した全ての箇所が有効なのは、 Go コンパイラが必要な外部のパッケージを探す場合のみ。逆に 1 つ目の GOPATH しか有効にならないのは、go get により外部のパッケージをダウンロード・インストールする場合らしい。
参考:https://qiita.com/chano2/items/ea76cc503e651f07bfb0
余談:mockgen で生成されたファイル一覧を表示
ついでに mockgen で生成したファイルの一覧を取得した。
日付表示でラフにスクリーニングし($7>15
)、ファイル名に mock を含むことを要求($9 ~ /.*mock.*/
)した。誰かもっとスマートな方法を教えてください。
$ ls -ulR $(find . -type f) | awk '{if($7>15 && $9 ~ /.*mock.*/){print $6" "$7" "$8" "$9}}’
余談の余談:GOPATH, GOROOT の表示
$ echo ${GOPATH}
$ echo ${GOROOT}
ではなく、
go env GOPATH
go env GOROOT
を用いた方がいい。デフォルト(環境変数として設定していない)の場合は echo では表示されないからだ。
参考:https://qiita.com/YumaInaura/items/3372186e2c11a45c65d8