Spring-MVC/ステップ・バイ・ステップ

2008/03/23からのアクセス回数 19601

プログラムのデバッグできるようになりましたので、次はmavenを使ってプログラムのテストが できるようにしましょう。

Springの提供するテストには、

  • 単体テスト
  • 結合テスト
  • トランザクションテスト

があります。 ここでは、JunitとMockHttpServletRequestの使い方について説明します。

テストの準備

ディレクトリの追加

mavenのWebアプリケーションにテストケースを組み込む場合には、以下のディレクトリを追加します。

+ mvc-convention/
|- pom.xml
|-+ src/
  |-+ main/
  | |-+ resources/
  | |-+ webapp/
  |    |-+ WEB-INF/
  |    |- web.xml
  |    |- index.jsp
  |-+ test/
    |-+java/ ← 追加
    |-+resources/ ← 追加
  • src/test/java/ には、テストケースのjavaプログラムを配置
  • src/test/resources/ には、テスト用のリソースファイルを配置

を追加します。

ライブラリの追加

次に、テストに使用するSpringのライブラリをpom.xmlに追加します。

テストには、spring-testが必要です。MVNRepositoryで検索すると、

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-test</artifactId>
    <version>2.5.2</version>
</dependency>

をpom.xmlに追加します。

クラスパスの変更

以下のコマンドを実行して.project, .classpathファイルを更新します。

$ rm .project .classpath
$ mvn eclipse:eclipse -DdownloadSources=true

テストケースの作成

準備ができましたので、テストケースを作成しましょう。

Springでは、

  • AbstractDependencyInjectionSpringContextTests
  • AbstractTransactionalSpringContextTests
  • AbstractTransactionalDataSourceSpringContextTests

のテストケースを提供しています。今回はトランザクションのテストが可能なAbstractDependencyInjectionSpringContextTestsを使用することにします。

クラスの単体テスト

最初にStubRecipeManagerのfindByIdの単体テスト作ってみましょう。

src/test/java以下にSampleTestCase.java として以下のファイルを作成します。

import org.springframework.showcase.coverc.domain.Recipe;
import org.springframework.showcase.coverc.service.StubRecipeManager;
import org.springframework.test.AbstractDependencyInjectionSpringContextTests;


public class SampleTestCase extends AbstractDependencyInjectionSpringContextTests {

	public void testFindById() {
		StubRecipeManager manager = new StubRecipeManager();
		
		Recipe recipe = manager.findById(1L);
		assertNotNull(recipe);
		assertEquals("Goats Cheese with beetroot sauce", recipe.getName());
	}
}

JUnitでは、個々のテストは、''public void testXXXX()'のように定義しなければなりません。

testFindByIdでの処理は以下の通りです。

  • StubRecipeManagerのインスタンスmanagerを作成する
  • managerにfindByIdメソッドでIdが1のrecipeを取り出す。
  • recipeがNullでなく、nameが"Goats Cheese with beetroot sauce"であることを確認する

単体テストの実行

テストケースができたので、実際にJunitを使った単体テストをしましょう。

mavenでは、単体テストを簡単に実行するために、testというゴールを提供しています。

コマンドラインから以下のコマンドを入力すると、自動的にSmapleTestCase.javaをコンパイル、テストを実行します。

$ mvn test
Listening for transport dt_socket at address: 8000
[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Building mvc-convention Maven Webapp
[INFO]    task-segment: [test]
[INFO] ------------------------------------------------------------------------
-- 途中省略
-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running SampleTestCase
2008/03/23 16:47:00 org.springframework.test.AbstractDependencyInjectionSpringContextTests prepareTestInstance
情報: ApplicationContext has not been configured for test [SampleTestCase]: dependency injection will NOT be performed.
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.458 sec

Results :

Tests run: 1, Failures: 0, Errors: 0, Skipped: 0

テストで1つの情報(Macでは???と文字化けします)がでます。

  • SpringのBean定義が設定されていない旨の警告

テストの結果は、Results:以下の

Tests run: 1, Failures: 0, Errors: 0, Skipped: 0

で確認します。 1個のテストを実行し、失敗、エラー、スキップがすべて無いことが確認できます。

もちろん、Eclipseを使って単体テストを実行することも可能です。

  • Runメニューから"Run..."を選択する
  • RunダイアログのJUnitを選択し、右クリックでNewを選択する
  • RunダイアログのRunボタンを押す

とJUnitが実行します。

Mockオブジェクトを使った結合テスト

次に、SpringのBean定義ファイルを使った結合テストの方法について説明します。

リソースのコピー

最初にBean定義ファイルをテスト用リソースファイルにコピーします。

  • src/test/resources/にWEB-INFディレクトリを追加します
  • src/main/webapp/WEB-INF以下のapplicationContext.xml, coverc-servlet.xmlを src/test/resources/WEB-INFにコピーします

coverc-servlet.xmlのSwitchBoardContrllerの定義に以下のようにidを追加してください。

    <bean id="switchBoadController" class="org.springframework.showcase.coverc.web.SwitchBoardController"
          parent="baseRecipeController"/>

テストケースでのBean定義ファイル設定方法

テストケースで使用するSpringのBean定義ファイルは、getConfigLocationsメソッドで定義 する約束になっています。

getConfigLocationsは以下のように定義します。

	public String[] getConfigLocations() {
		return new String[] {
				"WEB-INF/applicationContext.xml",
				"WEB-INF/coverc-servlet.xml"
		};
	}

テストメソッドの追加

Mockオブジェクトを使った結合テストの例を以下に示します。

  • MockHttpServletRequestを使ってMockのHTTPServletRequestを生成します
  • SpringのBean定義に従って生成されたApplicationContextからswitchBoadControllerを取り出します
  • switchBoadControllerにHTTPServletRequestを処理(handleRequest)させます
  • hadleRequestで返されたModelAndViewのviewNameがnullであることを確認します
  • ModelAndViewのmodelからrecipeListを取り出します。
  • recipeListのサイズが3であることを確認します
  • 最初のRecipeのNameが”Goats Cheese with beetroot sauce”であることを確認します
	public void testIntegrated() throws Exception {
		MockHttpServletRequest req = new MockHttpServletRequest("POST","switchBoadController/listRecipes.htm");
		
		SwitchBoardController	controller = 
				(SwitchBoardController)getApplicationContext().getBean("switchBoadController");
		
		ModelAndView mv = controller.handleRequest(req,new MockHttpServletResponse());

		assertNull(mv.getViewName());
		List list = (List)mv.getModel().get("recipeList");
		assertEquals(3, list.size());
		Recipe recipe = (Recipe)list.get(0);
		assertEquals("Goats Cheese with beetroot sauce", recipe.getName());
	}

結合テストの実行

Bean定義ファイルを追加し、Mockオブジェクトを使った結合テストを実行すると以下のように 出力されます。

$ mvn test
-- 途中省略
-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running SampleTestCase
2008/03/23 18:28:31 org.springframework.test.AbstractSingleSpringContextTests 
-- 途中省略
Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.623 sec

Results :

Tests run: 2, Failures: 0, Errors: 0, Skipped: 0

2個のテストメソッドが正常に動作していることが確認できました。

コメント

この記事は、

選択肢 投票
おもしろかった 6  
そうでもない 2  
わかりずらい 10  

皆様のご意見、ご希望をお待ちしております。


(Input image string)


添付ファイル: fileSampleTestCase.java 1612件 [詳細]

トップ   編集 凍結解除 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2022-06-21 (火) 10:43:38 (667d)
SmartDoc