Goで生成モックがテスト対象パッケージをimportする場合は外部テストパッケージにする
Go
mockery
テスト
mockery 等で生成したモックを集約パッケージ(test/mocks など)に置く構成では、モック対象インターフェースの入出力型がどのパッケージに定義されているかによって、テストが import cycle で書けなくなることがある。
発生条件: インターフェースの Input/Output 構造体を interactor 等の実装パッケージ自身に定義していると、生成モックがそのパッケージを import する。すると同パッケージ内テスト(package foo)からモック集約パッケージを import した時点で import cycle not allowed in test になる。DTO を別パッケージ(usecase/dto/... 等)に分離しているインターフェースでは起きない。
対処の選択肢:
- 外部テストパッケージ(
package foo_test)にする(最小変更): 外部テストパッケージは「テスト対象を import するパッケージ」を import してもサイクルにならない。エクスポートされた API 経由のテストになるため、振る舞い駆動テストとしてはむしろ健全。 - 入出力型を独立した dto パッケージへ移す(設計としては根治だが既存コードの変更が必要)。
補足: unexported な純粋関数もテストしたい場合は、同パッケージ内テスト(モック不要のもの)と外部パッケージテスト(モック使用)の2ファイルに分けられる。Go は foo と foo_test の2パッケージのテストファイル共存を許している。
気づき方: テスト追加時に import cycle not allowed in test が出たら、まず生成モックの import 文を見て、どの実装パッケージに依存しているかを確認する。