SpringMVCのControllerをJUnit4でテストする

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クラスのテスト出来るかな~
って気がする今日この頃です。

現場で使えるソフトウェアテスト Java編
飯山 教史 町田 欣史 高橋 和也 小堀 一雄
翔泳社
売り上げランキング: 49328

コメント

タイトルとURLをコピーしました