SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

ASP.NET MVCフレームワーク 正式版 入門

ASP.NET MVCの開発応用編1
~リポジトリパターンをマスターする~

ASP.NET MVCフレームワーク 正式版 入門(4)

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

3.テストクラス(Controller)への適用

 ASP.NET MVCで容易になった単体テストですが、リポジトリパターンを扱うことでより安全に、精度の高いテストを実行できます。今回は似たようなテストになってしまうので2種類のテストを確認してみたいと思います。

 実際のサンプルは以下の図のようになります(図3~4)。

図3 テスト失敗時の画面
図3 テスト失敗時の画面
図4 テスト成功時の画面
図4 テスト成功時の画面

Indexメソッドの検証

 それでは実際にテストを行います。まずは一番シンプルなIndexから。

PubsControllerTestクラスの一部
using RepositorySample.Controllers;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Web.Mvc;
using Moq;
using RepositorySample.Tests.Model;
using System.Linq;

namespace RepositorySample.Tests
{

    <中略>

        // テストデータの作成
        PubsController CreateTestPubsController()
        {
            var TestData = FakePubsData.CreateTestData();
            var repository = new Model.PubsRepositoryTest(TestData);

            return new PubsController(repository);
        }

    <中略>

        [TestMethod()]
        public void IndexTest()
        {
            // PubsControllerの準備
            PubsController pubsCon = CreateTestPubsController();
            // 実行
            var result = pubsCon.Index();
            // 検証
            Assert.IsInstanceOfType(result, typeof(ViewResult));
        }

 最初にCreateTestPubsControllerメソッドを作成し、すべてのテストメソッドで共通的に利用できるPubsControllerを生成します。

 CreateTestPubsControllerメソッド内では、CreateTestDataメソッドでList型を生成し、その値をパラメタとしてPubsRepositoryTestに渡します。最後に、リポジトリモッククラスのパラメタを持たせたPubsControllerを返します。

 IndexTestメソッド側では、生成されたPubsControllerに対してIndexメソッドを実行した結果をresult変数に格納しています。最後にresult変数がViewResultのインスタンスかどうかをIsInstanceOfTypeメソッドを使って検証しています。

Editメソッドの検証

 第2回ではFormCollection型がViewPage側で入力された項目すべてのデータを持つCollectionであることを解説しました。利用方法はString型のキーとデータを同時に指定することで、データを格納します。このFormCollectionを有効活用するシナリオとして単体テスト時が挙げられます。つまり、通常実行時は活躍の場所がなくとも、単体テスト時に入力項目を用意して埋め込めば入力ポスト時のテストが行えるのです。

PubsControllerTestクラスの一部
using RepositorySample.Controllers;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Web.Mvc;
using Moq;
using RepositorySample.Tests.Model;
using System.Linq;

namespace RepositorySample.Tests
{

         <中略>

        // テストデータの作成
        PubsController CreateTestPubsController()
        {
            var TestData = FakePubsData.CreateTestData();
            var repository = new Model.PubsRepositoryTest(TestData);

            return new PubsController(repository);
        }

        <中略>

        [TestMethod()]
        public void EditTest()
        {
            // PubsControllerとFormCollectionの準備
            PubsController pubsCon = CreateTestPubsController();
            var form = FakePubsData.CreateTitlesFormCollection();
            pubsCon.ValueProvider = form.ToValueProvider();

            // 実行
            ActionResult result = (ActionResult)pubsCon.Edit("1", form);

            // 検証
            Assert.AreEqual(5, pubsCon.ModelState.Count);
            Assert.AreEqual("Tamaki's Photo Diary", pubsCon.ModelState["title"].Value.AttemptedValue);
        }

 Edit部分では"既に登録されているデータ(ここではモックデータ)と、変更があった部分のデータ(FormCollectionによるデータ)"の差分が適切に編集更新されているかどうかをテストします。

 Indexの時同様にCreateTestPubsControllerメソッドでPubsControllerを生成します(モックデータの生成)。続いて、FakePubsDataクラスで用意した、FormCollectionのモックデータを生成(更新部分のデータ作成)します。

 CreateTitlesFormCollectionメソッドを使い、取得したFormCollectionのデータをPubsControllerクラスのValueProviderプロパティに格納します。

 ValueProviderプロパティとは、UpdateModelメソッドの更新内容パラメタとして、利用できるプロパティです(UpdateModelメソッドは第一パラメタに更新対象を、第2パラメタに更新内容を指定できます)。FormCollectionはView側の入力フォームのデータをすべて持っているので、その中から更新したい内容を渡すプロバイダとしてValueProviderプロパティがあると捉えてもらっても構いません。

 続いて、Editメソッドを実行した結果をresult変数に格納しています。最後にFormCollectionのデータの数が一致するか、ModelStateの数でテストします。

 ModelStateコレクションは、アクションメソッドに渡されているプロパティまたはModelの状態を格納しているコレクションです。また、エラーなどの内容も格納されるのは第2回の検証機能で紹介したとおりです。

 続けて、FormCollectionデータ作成時に格納した値と一致するかもModelState["キー名"].Value.AttemptedValueプロパティを使い確認します。AttemptedValueプロパティとは、View側で実際に表示されるフォーマット前Stringの値が入っています。

 リポジトリパターンを扱うことで、大抵ActionResultが返されるASP.NET MVCにおけるテストの容易さ、確実性の向上が望めることがお分かりいただけたかと思います。

まとめ

 今回はASP.NET MVCで実開発を行う際に利用されるメジャーな開発パターンであるリポジトリパターンについて概要とメリットを紹介しました。今回触れた内容は単純にデータアクセスロジックをControllerから取り出すところまででしたが、さらに機能ごとに分離させることで、Controllerをよりスッキリした記述に変えることなども可能です。

 また、複雑なシステムであっても、今回触れたリポジトリパターンを活かすことでテスト、開発共にパワフルに行えます。ぜひ、本稿の内容を足がかりにリポジトリパターンをマスターしていただければと思います。 

参考文献

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
ASP.NET MVCフレームワーク 正式版 入門連載記事一覧

もっと読む

この記事の著者

山田 祥寛(ヤマダ ヨシヒロ)

静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるReact実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

WINGSプロジェクト ナオキ(ナオキ)

WINGSプロジェクトについて>有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。2018年11月時点での登録メンバは55名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂きたい。著書記事多数。 RSS X: @WingsPro_info(公式)、@WingsPro_info/wings(メンバーリスト) Facebook

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/4354 2009/10/05 14:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング