SpringMVCで作ったコードに対してJUnitでテストしたかったのですが、 当初はあんまりSpringに縛られない感じでやろうかなぁって思ってたものの、 自分でガツガツnewしてどうのこうのっていうのは辛すぎます、と。 出来れば普通のコード書くのと同じようにアノテーションベースでやっていきたいです、と。 ■ SpringJUnit4ClassRunner JavaDocみると、JUnit4.5~のカスタムエクステンションで、 TestContextManagerを使ってbean定義を読み込んでDIしてくれて、 テスト用のサポートクラスやアノテーションを関連付けてくれる的な事が書いてあります。 んま、Springのモジュール動かすのにナイスなクラスって事で。 ちゃんとソース読んでないからアレですが、リフレクションとかでホゲホゲしてそうですね。 ■ 共通テストクラス どのコントローラーのテストでも同じ事しそうだなっていうのは 親クラスにまとめる事にしました。 クラスに付けたアノテーション的には ・上記のSpringJUnit4ClassRunner使うぜ ・bean定義してあるコンテキストxmlに関する設定 になります。コンテキストのxmlに関しては何も指定しないと、 『テストクラス名-context.xml』 って感じで読み込まれます。今回は安直に AbstractControllerTest なんていう クラス名にしたので『AbstractControllerTest-context.xml』って感じ。 ローカル環境のdataSourceの定義や、外部接続系のクラスで、 モックがどうのとかそういうのがあればココに定義するとイイ感じかと。
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration public class AbstractControllerTest { @Autowired protected ApplicationContext context; protected MockHttpServletRequest request; protected MockHttpServletResponse response; protected AnnotationMethodHandlerAdapter adapter; @Before public void setUp() { request = new MockHttpServletRequest(); response = new MockHttpServletResponse(); response.setOutputStreamAccessAllowed(true); adapter = new AnnotationMethodHandlerAdapter(); } }
上記のようにHTTP系はMockオブジェクト使ってやりくりして、 アダプターを使うとコントローラーが叩けるみたいです。詳細は実際のテストクラスで。 ■ Controllerテストクラス 上記の親クラスを継承して、テストしたいコントローラーをDIします。 @BeforeってつけとくとsetUpメソッド的な動き方をしてくれるっぽいのですが、 CSVファイルとかにテストデータ定義して~とか、よくあるそういうのやりたいな、と… #あるのかな…。そういう便利ツール。Seasarみたいに。
public class HomeControllerTest extends AbstractControllerTest { @Autowired private HomeController controller; @Before public void prepareData() { System.out.println("Prepaing Data"); }
んで、いよいよ本番です、と。 なんとなく直観的に分かりやすい感じになってるかな?と思います。 HTTPリクエストに必要な情報セットしてadapter.handle叩くと、 どのJSP?とか、JSPに渡すオブジェクトを取得してアサートとか。 #なんかキャストしてワーニングをuncheckedで潰すのとか気が向かないけど。。
@Test @SuppressWarnings("unchecked") public void testHome() { request.setMethod("GET"); request.setRequestURI("/"); try { ModelAndView mav = adapter.handle(request, response, controller); ModelAndViewAssert.assertViewName(mav, "home"); List list = (List) mav.getModel().get("itemList"); assertEquals("itemList Size", 3, list.size()); } catch (Exception e) { e.printStackTrace(); fail(); } }
こんな感じでやってけば楽してSpringMVCのControllerクラスのテスト出来るかな~ って気がする今日この頃です。