ダウンロード サンプルファイル (6.4 MB)
moqの基本
実際にmoqを使うための基本を解説します。
moqではMockクラスが基本となります。そしてMockクラスを扱う上で最低限抑えておくべきメソッドはSetupメソッドです。
Setupメソッドのパラメータとしてラムダ式を記述します。モックオブジェクトはラムダ式の右辺で記述したメソッドの振る舞いを持ちます。Setupメソッド内で設定されたメソッドの戻り値はReturnメソッドのパラメータに記述します。
説明だけだとイメージしづらいと思いますので実際の構文を見てみましょう。構文例は以下のとおりです。
// テストしたいクラスのモックオブジェクトを作成 Mock<テストしたいクラス> mock = new Mock<テストしたいクラス>(); mock.Setup(m => m.テストしたいメソッド名(パラメータ)).Returns(理想の戻り値);
モックオブジェクト生成構文は上記のとおりです。
MVCのControllerContextのモックオブジェクト生成時の記述例もご紹介します。
// Controllerのモックオブジェクト生成例
Mock<ControllerContext> mock = new Mock<ControllerContext>();
mock.SetupGet(p => p.HttpContext.User.Identity.Name).Returns("Naokio");
ユーザー認証のフィルターが正確に動作しているかどうかテストしたい場合、上記モックオブジェクト生成コードを使うことになります(上記コードでは、Naokioというユーザー名を取得できるモックオブジェクトを生成しています)。
本来はアプリケーションサーバーを立てて実際に動作させて、ユーザーを用意しなければユーザーネームは取得できませんが、moqを使うことで、HttpContextオブジェクトやユーザーをあたかも実在しているかのように振る舞わせるモックオブジェクトを生成できます。
なお、設定したモックオブジェクトを取得するにはObjectプロパティを使用します。取得したモックオブジェクトはモックオブジェクト生成時に指定したクラスと同様の使い方ができます。
moqを利用する上でお作法が1つあります。それは、モックオブジェクト元のクラスの対象メソッドにvirtual修飾子を付けるというお作法です。テストを先に記述する場合、形だけのクラスやメソッドを作成しますが、moqではメソッドのオーバーライドを実施するため、virtual修飾子が必要になります。
なお、ControllerContextのプロパティやメソッドはvirtualで記述されているため、このお作法を意識することなくモックオブジェクトの作成が可能です。
続いて、ラムダ式内で記述するメソッドのパラメータに活用するItクラスについて紹介します。Itクラスは単体テストをより簡易に分かりやすく記載するための条件判定を実施できるメソッドを保有し、条件にマッチした場合Returnsメソッドの設定値を取得できます。条件判定をメソッド単位で実現できるのでIf文などの記載も不要になり可読性も向上します。
Itクラスで活用するメソッドは以下のとおりです。
| メソッド名 | 概要 |
| IsAny | パラメータで指定された型が渡された場合すべて許容する |
| IsInRange | パラメータで指定した範囲内の値が渡された場合許容する |
| IsRegex | パラメータで指定した正規表現にマッチする場合許容する |
構文例は以下のとおりです。
// テストしたいクラスのモックオブジェクトを作成 Mock<テストしたいクラス> mock = new Mock<テストしたいクラス>(); mock.Setup(m => m.テストしたいメソッド名(It.IsAny<型名>(パラメータ))).Returns(理想の戻り値); mock.Setup(m => m.テストしたいメソッド名(It.IsInRange<型名>(レンジ開始値,レンジ終了値,レンジの種類))).Returns(理想の戻り値); mock.Setup(m => m.テストしたいメソッド名(It.IsRegex(正規表現))).Returns(理想の戻り値);
各メソッドの利用例は以下のとおりです。
// すべてのstring型を許容し文字列を返す
mock.Setup(m => m.テストしたいメソッド名(It.IsAny<string>())).Returns("文字列取得しました。");
// 5~15以内の数値の場合許容し文字列を返す
mock.Setup(m => m.テストしたいメソッド名(It.IsInRange<int>(5,15,Range.Inclusive))).Returns("5~15の範囲の数値を取得しました。");
// 正教表現にマッチした場合許容し文字列を返す
mock.Setup(m => m.テストしたいメソッド名(It.IsRegex(^(WINGSプロジェクト|wingsプロジェクト)$))).Returns("正規表現とマッチしました。");
MVCでは基本的に上記クラスとメソッドの活用を把握していれば単体テストを記述できるようになります。
まとめ
今回はMVC 3のサンプルプロジェクトに対する単体テストの記述方法を、単体テストを利用する上でのTipsを織り交ぜながら紹介しました。今回のまとめは以下のとおりです。
- 単体テストはバグを早期発見しコードの品質を高めることができる
- .NETにおける単体テストフレームワークとしてMSTestがProfessional Edition以上で利用できる
- テストで扱うモックはmoqを使用することで単体テストが容易に実現できる
以上を踏まえて次回は第4回で作成したDIプロジェクトの単体テストを記述しつつ、単体テストのポイントをご紹介していきます。お楽しみに。
参考文献
この記事は参考になりましたか?
既に会員の方はを行ってください。
- ASP.NET MVC3入門連載記事一覧
-
- ASP.NET MVC 3における単体テストの基本と記述方法
- ASP.NET MVC 3における単体テストの基礎
- ASP.NET MVC 3におけるDI実装のポイント
- この記事の著者
-
山田 祥寛(ヤマダ ヨシヒロ)
静岡県榛原町生まれ。一橋大学経済学部卒業後、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本格入門」「これからはじめるLaravel実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数。
※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です
-
WINGSプロジェクト ナオキ(ナオキ)
<WINGSプロジェクトについて>有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。 2026年時点での登録メンバは約50名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂きたい。著書、記事多数。 RSS X: @WingsPro_info(公式)、@WingsPro_info/wings(メンバーリスト) Facebook
※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です
この記事は参考になりましたか?
この記事をシェア
