Deep Insider の Tutor コーナー
>>  Deep Insider は本サイトからスピンオフした姉妹サイトです。よろしく! 
特集:ASP.NET MVC Contribのテスト支援機能(後編)

特集:ASP.NET MVC Contribのテスト支援機能(後編)

URLパターンを用いてテストを行う

2013年7月23日

URLルーティングの設定を変更しながら、ASP.NET MVCアプリのテストを追加していく方法について説明。また、MvcContribのテスト支援機能以外の機能についても簡単に紹介する。

  • このエントリーをはてなブックマークに追加

 MVC Contribは、ASP.NET MVCを便利に使うためのオープンソース・ライブラリだ。前編では、MVC Contribを活用してテストを簡単に行う方法について紹介した。後編となる本稿では、URLルーティングの設定を変更しながら、テストを追加していく方法について解説する。コードはC#で記述する。

新しいURLルーティングとテストを追加

 それでは、新しいURLパターンを追加していこう。ここでは、前編で紹介した「/article/100/page/2(100個目の記事の2ページ目)」というURLをテストするとしよう。このURLであれば、ArticleControllerのIndexメソッドが呼び出され、第1引数に「100」が、第2引数に「2」が渡されることを想定している。

コントローラーの記述

 まず、最初に呼び出されるコントローラーを以下のように記述する。Indexメソッドでは、記事ID「aid」とページ・ナンバー「pagenum」を引数として受け取る。

C#
using System.Web.Mvc;

public class ArticleController : Controller
{
  public ActionResult Index(int aid, int pagenum)
  {
    // 本来はaidやpagenumを使って処理を行う
    return View();
  }
}
ArticleControllerのIndexメソッドを記述(ArticleController.cs)

テストの記述

 次に、テストを記述する。ここでは、前回作成した「RouteConfigTest」というテスト・クラスの中に、「/article/100/page/2」というURLのテストを記述する(次のコードを参照)。

C#
[TestMethod]
public void 記事ペジが正しく呼び出されるはず()
{
  "~/article/100/page/2".Route().ShouldMapTo<ArticleController>(action => action.Index(100, 2));
}
新しいURLルーティングをテストするコードを追加(RouteConfigTest.cs)

 前回のテストと同様にShouldMapToメソッドを呼び出してテストを行っている。ここでは、アクションメソッドに「Index(100, 2))」という引数を指定している点に注目してほしい。第1引数のaidに「100」が、第2引数のpagenumに「2」がセットされることを想定している。

 このようにMVC Contrib TestHelperでは、ラムダ式でテストを記述できるため、コントローラーのシグネチャが変わったときにコンパイル・エラーで気付けるメリットがある。

テストがエラーとなることを確認

 それでは、テストを実行してみよう(次の画面はその実行結果)。まだURLルーティングを設定していないため、テストはエラーになるはずである。

テスト・ケースがエラーとなることを確認する

 追加したテストがエラーになることを確認できた。ルーティングを追加するときは、既存のテストが全部パスしていて、追記したテストだけがエラーになっていることを確認しておくとよいだろう。

ルーティングの設定を追加

 それでは、記事用のURLルーティング設定を(次のコードのように)追加してみよう。

C#
public class RouteConfig
{
  public static void RegisterRoutes(RouteCollection routes)
  {
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    //  新しいルート設定を追加(今回のテスト対象)
    routes.MapRoute(
      name: "Article",
      url: "article/{aid}/page/{pagenum}",
      defaults: new { controller = "Article", action = "Index" }
    );

    // 既定ルート
    routes.MapRoute(
      name: "Default",
      url: "{controller}/{action}/{id}",
      defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
    );
  }
}
記事用のURLルーティングの設定(Articleルート)を追加(RouteConfig.cs)

 URLルーティングを設定するには、MapRouteメソッドを用いてURLのパターン文字列を指定する。優先度が高いルートを先に指定する必要があるため、Defaultルートの前に新しいArticleルートを追加している。

 URL設定ではマッチングさせるパターン文字列を記述する。完全一致だけではなく「{中かっこ}」を用いた部分一致を記述できる。ここでは「article/{aid}/page/{pagenum}」と書くことで、記事IDとページ番号をパラメーターとして受け取るようにしている。

 なお、URLルーティングの設定方法については、この記事を参考にするとよいだろう

テストが成功することを確認

 再びテストを実行してみよう。今度は(次の画面のように)全てのテストが成功するはずである。

テストコードが成功することを確認する

 このような手順でテストを実施することで、既存のルーティング設定を壊すことなく、新しいルーティングを追加できる。

HTTPメソッドのテスト

 続けて、別のパターンのテストについても見ていこう。開発をしていると、GETやPOSTといった特定のHTTPメソッドのルーティングを制御したいケースもあるだろう。この場合のテストの書き方について紹介する。

 ここでは、記事をPOSTでアップロードする「article/{aid}/upload」いうURLを追加してみる。

コントローラーの記述

 まず、呼び出されるコントローラーを記述する。呼び出されるUploadメソッドでは、引数として記事ID「aid」とファイル「uploadFile」を受け取る。

C#
public class ArticleController : Controller
{
   ……省略……

  // リクエストがHTTP POSTのときのみ呼び出される属性
  [HttpPost]
  public ActionResult Upload(int aid, HttpPostedFileBase uploadFile)
  {
    // 本来はaidやuploadFileを使って処理を行う
    return View();
  }
}
コントローラーにUploadメソッドを追加

HTTPメソッドに応じたテスト

 次に「/article/100/upload」というURLのテストを記述する

C#
[TestMethod]
public void 記事アップロドが正しく呼び出されるはず()
{
  "~/article/100/upload".WithMethod(System.Web.Mvc.HttpVerbs.Post)
    .ShouldMapTo<ArticleController>(action => action.Upload(100, null));
}
HTTPメソッドに対応したテスト・コード

 ここでのポイントはRouteメソッドの代わりにWithMethodメソッドを使っていることである。WithMethodメソッドの戻り値はRouteメソッドと同じくRouteDataクラスである。そのため、ShouldMapToメソッドを呼び出して、アクションのテストを行うことができる。WithMethodメソッドの引数にPostを渡すことでテスト対象のリクエストがPOSTメソッドであることを示している。

ルーティングの設定を追加

 最後に、URLルーティングの設定を追加する。POSTだけルーティングするには、constraintsパラメーターにて「httpMethod」を設定する。

C#
public static void RegisterRoutes(RouteCollection routes)
{
  ……省略……
  // 記事ページにアップロード(POSTのみ対象)
  routes.MapRoute(
    name: "Article Uplopad",
    url: "article/{aid}/upload",
    defaults: new { controller = "Article", action = "Upload" },
    constraints: new { httpMethod = new HttpMethodConstraint("POST") }
  );
  ……省略……
}
POST用のURLルーティング設定を追加

テストの実行

 この状態でテストを実行するとテストが成功する。MVC Contrib TestHelperを使うことで、ブラウザを使用せずにさまざまなテストが可能になることが分かったと思う。

MVC Contrib TestHelperが提供するFakeクラスについて

 なお、本稿ではルーティングのテスト方法について紹介したが、TestHelperには、テストに役立つFakeクラスも含まれている。Fakeクラスとは例えば、セッション情報やログイン状態を偽装するクラスなどである。

 主要なFakeクラス(FakeHttpContext、FakeHttpRequest、FakeHttpResponse、FakeHttpSessionState、FakeIdentity、FakePrincipal)とBuilderクラス(TestControllerBuilder)のクラス図を以下に記載しておくので、必要があれば利用してみるとよいだろう。

MVC Contribが提供しているFakeのクラス群

ほかのMVC Contribの機能について

 今回は、MVC Contribのテスト支援機能について紹介した。Codeplexのサイトによれば、MVC Contribではテスト支援機能以外にも多くの機能が提供されている。

Contrib区分機能・部品
Portable Areas 複数のプロジェクトで使用できるポータブルなエリア(区分)
UI Helpers GridコントロールなどのUI部品
Model Binders Derived Type Model Binder、Castle Binder(Castleプロジェクト連携)などのモデル・バインダー
Controller Factories Spring.Net、Unity、Castle Windsor、StructureMapといったDIコンテナ連携
Controllers AcceptPostAttribute、強い型のRedirectToAction、Fluent Controllerなど
Filters PostOnly Filter、PreCondition Filter、Layout Filterなどのフィルタ
View Engines Brail、NDjango、NHaml、NVelocity、SharpTiles、Spark、StringTemplate、XSLTなどのビュー・エンジン
Unit Testing Library ユニット・テストのためのライブラリ
Utilities ユーティリティ機能
T4MVC T4テンプレートを用いたユーティリティ
MVC Contribの一覧(Documentページより)

 Channel9で動画も公開されているので、気になるライブラリがあれば、活用を検討してみてはいかがだろうか。

特集:ASP.NET MVC Contribのテスト支援機能(後編)
1. ASP.NET MVCアプリのURLのテストを簡単に行う

ASP.NET MVCを便利に使うためのオープンソース・ライブラリ「MvcContrib」のテスト支援機能を活用して、ASP.NET MVCアプリのURLをテストする方法を説明する。

特集:ASP.NET MVC Contribのテスト支援機能(後編)
2. 【現在、表示中】≫ URLパターンを用いてテストを行う

URLルーティングの設定を変更しながら、ASP.NET MVCアプリのテストを追加していく方法について説明。また、MvcContribのテスト支援機能以外の機能についても簡単に紹介する。

サイトからのお知らせ

Twitterでつぶやこう!