Spring × SpockのテストでsetupSpecにAutowiredされたコンポーネントを使いたい

今のプロジェクトではJUnit5よりも好んでSpock (Groovy)を使ってます。

Spring Boot製アプリケーションのテストを行う際に、 setupSpec (テストクラス内で一度きりの初期化)メソッド内で、 Autowired されたコンポーネントを使いたかったのですが、使えなかったので、その対応方法のメモです。

まずは前提ですが、

  • spring-spockはなるべく最新のバージョンを使いましょう
  • Spockのテストクラスには @RunWith(SpringRunner)つけない ようにしましょう

失敗ケース

  @Shared
  @Autowired
  HogeService hogeService

  def setupSpec() {
      hogeService.doSomething()
  }

成功ケース

  @Autowired
  HogeService hogeService

  @Shared
  boolean isInitialized = false

  def setup() {
      if (isInitialized) {
          return
      }

      hogeService.doSomething()
      isInitialized = true
  }

というわけで、 setupSpec を使うのをやめて、setup(テストメソッド側で毎回呼ばれる処理)に移しました。 ちなみに、 isInitialized を使った一連のコードは、なくても(テストの成否に)影響はないのですが、 hogeService.doSomething が1回だけ行えばよいような初期化処理であり、テストケースの数が多い場合、実行時間の面で有利です。

参考