気まぐれメモランダム / でたらめフィードバック

Springセッションスコープの単体テストは要Webアプリケーションコンテキスト

公開:

Java製WebアプリケーションフレームワークのSpringに業務で初挑戦することになりまして、Controllerの単体テスト実装で引っかかったのでメモを残しておきます。

SpringにはControllerの単体テスト方法として次の二種類が用意されています。

  1. Spring Bootの組み込みAPサーバーを使う方法
  2. 組み込みAPサーバーを使わず、代わりにSpring MVCのテストフレームワークであるMockMvcを使う方法

MockMvcを使う方法はさらに次の二種類に分かれます。

  1. SpringのWebアプリケーションコンテキストを自動構成で有効にする方法
  2. SpringのWebアプリケーションコンテキストを有効にせず、Webレイヤーの特定Controllerのみを対象とする方法

テスト対象は組み込みAPサーバーを使う方法がもっとも広く、Webアプリケーションコンテキストを有効にしない方法がもっとも狭くなります。テストコードでどのスコープを対象とするかは議論のあるところですが(私はいわゆる古典学派の立場が好み)、スコープが選択できるのは悪いことではありません。

とはいえ選択肢があるからといって常にすべてが選択可能とはかぎりません。セッション(Springではセッションスコープやセッションコンテキストといった表現を用いています)と関連付けるControllerの単体テストは選択肢が限られる単体テストにあたり、セッションのスコープ管理にはWebアプリケーションコンテキストが必要なため、Webアプリケーションコンテキストを有効にしない単体テストは利用できません。

これはSpringおよびMockMvcの仕組みを考えれば理解できます。

  • SpringはアノテーションでBean指定されたクラスのインスタンスを自動的に生成する。またコンストラクタやメソッド呼び出しの際に引数がBean指定したクラスであれば依存性注入(DI)の一環で自動生成したインスタンスを利用する
    • 逆に言えば、自動生成したインスタンスがなければDIを要求するコンストラクタやメソッドは呼び出せない
  • SessionScopeアノテーションを指定してセッション用としたクラスは自動生成のタイミングがセッション開始時になる
  • セッションはWebアプリケーションコンテキストと関連づくため、Webアプリケーションコンテキストが有効でなければ単体テストを実行できない

このように機序をたどれば理由は明白なのですが、Springに慣れない人間の試行錯誤にはまったく親切ではありません。仕組みからわかるように、Webアプリケーションコンテキストを有効にしない単体テストは利用できないという事実は Webアプリケーションコンテキストを有効にしない単体テストを実行しないとわからない からです。しかもその事実は例外の送出=単体テストの失敗報告という形で報告されます。単体テストの失敗なのかそもそも単体テストができなかったのかは失敗の内容を精査しなければなりません。Springに慣れていない開発者にとっては荷の重い作業と言えます。私は理解するまでずいぶん時間がかかりました。

アノテーションで動きを制御するSpringのやりかたはたしかに便利ではありますが、構造が隠蔽されてしまうという点ではかならずしも優れているとばかりは言えないように思います。今後は送出例外を工夫するなどのより原因の掴みやすい報告を期待したいところです。

以上、お役に立てば幸いです。

関連リンク

関連コンテンツ

Pick up work

最近のエントリ

アーカイブ

ブログ情報