Closed7

Goのモックライブラリの技術選定

abekohabekoh

個人的にモックライブラリにほしいもの。どれもJUnit + Mockitoでやってた頃の感覚に近くしたいためにほしい

  • interface以外もモック化可能
  • mockの振る舞い定義しなくてもスタブとして利用可能
  • リフレクションでテストコード内だけで完結
  • 記述量少なめ
  • privateメソッドでプリセットのモックをいい感じにまとめやすい。テストコードのリファクタリングがやりやすい
  • モックへの入力値の検査可能
abekohabekoh

GoMock

サンプル: https://github.com/abekoh/go-mock-libs/blob/main/application/app_gomock_test.go

  • Stars: 7.1k 一番有名
  • mockgenコマンドでモック生成
  • EXPECT()で振る舞いを定義
    • 定義すると呼び出しがないと怒られる、AnyTimes()をつければ解決
  • スタブらしくゼロ値をそのまま返すだけ、にも振る舞い定義する必要あり
  • Contrllerを使ってセットアップ&お片付けする必要あり
  • 引数チェックMatcherのデフォルト実装が自由度が低め。 こちら とか参考に自由度高いMatcher用意すると良さげ
  • 生成される引数、戻り値など interface{} だったりで元のコードとにらめっこする必要ある
abekohabekoh

mockery (testify)

サンプル: https://github.com/abekoh/go-mock-libs/blob/main/application/app_mockery_test.go

  • Start: 3.5k
  • 実体は stretchr/testify/mock で、それをCLIで簡単に実装できるようにしたやつ
  • mockery --all --keeptree と実行してみて go:generate 書かなくてもinterface全部のmock作ってくれた
  • 引数のチェックも mock.MatchedBy で簡単に実装できる
  • スタブ実装も振る舞い定義する必要あり
  • CLI機能豊富でいろいろできそう
  • GoMock同様 interface{} 多様、メソッド名もstringで指定なので元の実装にらめっこ必要
abekohabekoh

Moq

サンプル: https://github.com/abekoh/go-mock-libs/blob/main/application/app_moq_test.go

  • Stars: 1.3k
  • GoMockに似たコード生成
  • モックのフィールド値としてfunctionを持つものを生成し、それを書き換えることで振る舞い変える。シンプルながらよい
  • 引数チェックはfunctionの中にt.Errorf()入れたりassert.Equal()入れたりでよしなにできそう
  • timesとか無いが、XXXCalls() で呼び出した引数あとから呼べるので、そこで呼び出し回数チェックできる。ここでもassert.Equal()とかよしなに使える
  • interfaceと同じ階層であれば特に問題ないが、完全に別のディレクトリに置こうとすると動かない、同じpackageである必要あるっぽい
  • 引数、戻り値などinterface{}ではなくそのままの型なので型安全に実装できる
  • オプションでゼロ値を返すだけのスタブをデフォルトにできる
  • デフォルトのモックをprivate methodでまとめて定義→テストごとに必要なら上書き、といったことが簡単にできそう
abekohabekoh

所感

Moqがとてもよかった。Starsは少なめだが最近もメンテされている。
シンプルな実装であるがゆえ、柔軟にアサーションできてりテストコードリファクタリングができそう。
実務でも試してみることにする。

このスクラップは2022/10/15にクローズされました