ASP.NET MVCにおける単体テストと単体テストTips
今回は以下の順番でテストを実施します。
- URLルーティング
- リポジトリクラス
- コントローラー
今回は最初に挙動を決めるであろうURLルーティングからテストを実施していきます。なお、個別のテストに入る前にテストの実行方法について簡単にご紹介します。
テストはメニューまたはツールバーから実行できます。メニューから実行する場合は以下の手順で実施できます。
[テスト]-[実行]または[デバッグ]-[現在のコンテキストのテスト]または[ソリューションのすべてのテスト]を選択(図1)。
ツールバーから実行する場合は実行したいモードのテスト形式のボタンをクリックするだけです(図2)。
なお、テストを記載する際のポイントとしてテストコードの正確性を確認する作業があります。
テストコードを記述した後、理想値にあえて異なる値を設定し、テストを失敗させます。その後理想値と実行結果が一致するか確認することで、テストの正確性が得られます(図3~4)。
それでは個別のテストを確認していきましょう。
URLルーティングの単体テスト
URLルーティングのルーティングルールはGlobal.asaxファイル内のRegisterRoutesメソッドに記載します。MVCプロジェクト作成時は以下の2つの機能が実装されています。
- IgnoreRouteメソッドで{resource}.axd/{*pathInfo}というWebリソースへのアクセスルートの無効化
- 既定のルーティングルールとして{controller}/{action}/{id}の指定
例えばXXXX.axdと記載されているルートが無効化されているかを確認するテストや、CodeZineControllerクラスのarticleアクションメソッドに適当な記事番号を割り振っている場合、CodeZine/article/5754などのリクエストを正しく処理できるかを確認するテストを記述することになります。
実際のURLルーティングのテストコードは以下のとおりです。
// ①ルート無効化の確認テスト [TestMethod] public void RoutingTest() { //// 準備 モック作成とルートコレクションへの登録 RouteData actual; var mockcontext = new Mock<HttpContextBase>(); mockcontext.Setup(c => c.Request.AppRelativeCurrentExecutionFilePath) .Returns("~/routeHandler.axd"); var routes = new RouteCollection(); MvcApplication.RegisterRoutes(routes); //// 実行 モックと一致するルートを取得 actual = routes.GetRouteData(mockcontext.Object); //// アサート ルートの検証 Assert.IsNotNull(actual); Assert.IsInstanceOfType(actual.RouteHandler, typeof(StopRoutingHandler)); } // ②ルート確認テスト [TestMethod] public void RouteCheck() { //// 準備 モック作成とルートコレクションへのルート登録 RouteData actual; var mockcontext = new Mock<HttpContextBase>(); mockcontext.Setup(c => c.Request.AppRelativeCurrentExecutionFilePath) .Returns("~/CodeZine/article/5754"); var routes = new RouteCollection(); MvcApplication.RegisterRoutes(routes); //// 実行 モックと一致するルートを取得 actual = routes.GetRouteData(mockcontext.Object); //// アサート ルートの検証 Assert.IsNotNull(actual); Assert.AreEqual("CodeZine", actual.Values["controller"]); Assert.AreEqual("article", actual.Values["action"]); Assert.AreEqual("5754", actual.Values["id"]); }
①と②に分けていますが、基本的な部分は両方変わりありません。
それぞれ、最初にモックを作成しています。URLルーティングの単体テストのキモはルートを取得するGetRouteDataメソッドのパラメータであるHttpContextBaseクラスのモックを作成する点です。HTTPの情報を扱うオブジェクトを生成する場合、都度アプリケーションサーバーを起動し、実際にアプリケーションを実行しなければ生成できないHttpContextBaseオブジェクトを生成するのは手間ばかり増えテストの本質から離れてしまいます。しかし、Moqを使うことで簡単にメソッドなどのインターフェースのみを実装したダミーのオブジェクトとなるモックを作成できます。モック作成後、GetRouteDataメソッドのパラメータにモックを指定することでモックに指定したルートが取得できます。
最後にアサートでRouteDataオブジェクトが取得できているかをIsNotNullメソッドで確認し、各ルートが無効化されているか、理想値と同一か確認するだけです。
続いてリポジトリクラスの単体テストを見てみましょう。