【C#】【Mock】Moq ~ 初期設定編 ~


■ Moq

 * 読み方は、モッキュ

■ 環境設定 / NuGet編

https://blogs.yahoo.co.jp/dk521123/35596847.html
で行ったNuGetでインストールする

手順

[1] Visual Studio で [ツール]-[NuGetパッケージ マネージャー]-[パッケージ マネージャー コンソール]を選択
[2] 以下のコマンドを入力する

Install-Package Moq

参考文献

http://www.atmarkit.co.jp/fdotnet/aspnetmvc3/aspnetmvc3_09/aspnetmvc3_09_02.html
http://normalian.hatenablog.com/entry/20090908/1252392058
http://codezine.jp/article/detail/6493

■ 環境設定 / 手動設定編

http://blogs.wankuma.com/masaru/archive/2010/12/03/195469.aspx
に詳しい使用方法が書いてあるが自分用にまとめる。

手順

前準備(実行環境を作る)
テスト実行環境を作成するために
https://blogs.yahoo.co.jp/dk521123/21001377.html
の手順を行っておく
Moqを設定する
[1] 以下のDownLoadサイトから、Moqをダウンロードする(今回、Moq.4.0.10827を使用)
http://code.google.com/p/moq/downloads/list
[2] ダウンロードしたファイルを解凍し、
    Moq.dll(\Moq.4.0.10827\NET40\Moq.dll)を、VisualStudioのプロジェクトで参照させる。
[3] テストコードを作成(サンプルコードを参考に...)
[4] ビルドする
[5] テストを実行するために、VisualStudioの[ツール]-[NUnit]を選択し、テストを「Run」させる
   (※上記の「前準備」はこの[5]のために行った)

■ サンプル

http://journal.mycom.co.jp/articles/2009/06/15/moq/001.html
を参考にした。詳細な解説は以下を参照。
https://blogs.yahoo.co.jp/dk521123/21216313.html

モック対象インターフェイス

namespace NUnitForm
{
    public interface ISampleInterface
    {
        int Sum(int value1, int value);
    }
}

テストコード

using System;
using NUnit.Framework;
using Moq; // 追加
using NUnitForm;

namespace FormTest
{
    [TestFixture] // テストコードであることを表すために[TestFixture]属性をクラスにつける
    public class TestClass
    {
        Mock<ISampleInterface> mock;

        [SetUp] // テストコードの初期化のために[SetUp]属性をメソッドにつける
        public void SetUp()
        {
            // Mock作成
            this.mock = new Mock<ISampleInterface>();
            // Sum()が第一引数「1」、第二引数「2」で呼ばれたら「3」を返すように設定
            this.mock.Setup(x => x.Sum(1, 2)).Returns(3);
            // Sum()が第一引数「5」、第二引数「5」で呼ばれたら「10」を返すように設定
            this.mock.Setup(x => x.Sum(5, 5)).Returns(10);
        }

        [Test] // テスト項目を表すために[TestFixture]属性をメソッドにつける
        public void Test_Sum()
        {
            // Mockオブジェクト取得
            ISampleInterface obj = mock.Object;

            // Sum()が第一引数「1」、第二引数「2」で呼ぶ
            Assert.AreEqual(3, obj.Sum(1, 2));
            // Sum()が第一引数「5」、第二引数「5」で呼ぶ
            Assert.AreEqual(10, obj.Sum(5, 5));

            // Sum()が第一引数「2」、第二引数「1」で呼ぶ
            // 設定してないと、0を返す
            Assert.AreEqual(0, obj.Sum(2, 1));

            // モックが意図した通りに呼び出されたかどうかを確認
            mock.VerifyAll();
        }
    }
}

■ 制限事項

 [1] 対象クラスにデフォルト・コンストラクタが含まれていない場合
 [2] 対象クラスのメソッドが virtual でないメソッドをフックする場合

 ⇒ System.NotSupportedException が発生する
  (Microsoftのモック・スタブフレームワーク Moles であれば、解決できるとのこと。今度試したい)

関連記事

Moq関連

Moq ~ 初期設定編 ~
https://blogs.yahoo.co.jp/dk521123/21212662.html
Moq ~ 文法編 ~
https://blogs.yahoo.co.jp/dk521123/21216313.html
Moq ~ サンプルコード編 ~
https://blogs.yahoo.co.jp/dk521123/21217266.html