VisualStudio2010 SP1 + NUnit + Moles の環境を構築する

C#のテストを書いていたら、.NETのクラス自体のモックを作成したくなりました。
調べてみると、Molesを使えばできるとのことでした。
neue cc - Rx + MolesによるC#での次世代非同期モックテスト考察


ただ、ほとんどの記事はMSTestと組み合わせて使っているものであったため、NUnitと組み合わせて使えるようにした時の方法をメモします。

注意

すでにMolesの次の世代、Microsoft Fakesが登場しており、Molesのサイトにも以下のように記載されています。

The Fakes Framework in Visual Studio 2012 is the next generation of Moles & Stubs, and will eventually replace it. Fakes is different from Moles, however, so moving from Moles to Fakes will require some modifications to your code. A guide for this migration will be available at a later date.


Pex, Automated White box Testing for .NET - Microsoft Research

ただし、Microsoft Fakesは Visual Studio 2012 Ultimate でしか動作しないようです。Ultimate以外のエディション(できればExpress)でも使えるようになることを祈ります。



環境

セットアップ

stackoverflowにセットアップ方法が記載されています。
Trying to use Moles with NUnit. Getting "Moles requires tests to be an instrumented process" - Stack Overflow


ただ、VisualStudioやNUnitのバージョンが少々古いため、VS2010 + NUnit2.6系でもセットアップできる方法を残します。
なお、環境にはすでにNUnitはインストール済とします。

1. Molesのインストール

Molesの公式ページ Pex, Automated White box Testing for .NET - Microsoft Research から、リンクをたどり、以下のページよりダウンロードできます。
Visual Studio 2010 Moles x86 - Isolation Framework for .NET extension


インストールはウィザードに従い、インストールします。
(以下の説明では、Moles・NUnitともにデフォルトのインストール先を選んだものとしますので、適宜読み替えてください)


2. NUnit向けのMolesをビルド

以下のファイルを任意の場所へコピーして、解凍します。

C:\Program Files (x86)\Microsoft Moles\Documentation\moles.samples.zip


以下のプロジェクトをVS2010で開きます。

<解凍先>\moles.samples\moles\NUnit\Microsoft.Moles.NUnit.csproj


「VisualStudio変換ウィザードへようこそ」が開くので、変換します。(バックアップは不要)


変換後のプロジェクトが開いたところで、参照設定を確認します。
nunit.core.interfaces」に警告マークがついているため、参照の追加から、NUnitに含まれている「nunit.core.interfaces.dll」を選択します。
これにより、警告が消えます。


ビルドの構成については特に変更しないまま、メニューバーより、「ビルド」→「Micorsoft.Moles.NUnit のビルド」を選択します。
slnファイルの置き場所を聞かれるので、デフォルトのまま保存します。
ビルドが進行し、「ビルドがすべて正常に終了しました。」のメッセージが表示されれば完了です。



3. NUnitへMolesのファイルを追加

ビルドの結果出来上がった、以下の2つのファイルをコピーします。

コピー元 <展開パス>\moles.samples\moles\NUnit\bin\Debug
コピー先 C:\Program Files (x86)\NUnit 2.6.2\bin\addins
4. テストランナーの設定

Molesを使ったテストはNUnitGUIテストランナーでは動作しません。
VS2010からテストを実行できるように、外部ツールへ以下の設定を行います。
(メニューバーの「ツール」→「外部ツール」→「追加」ボタン より)

タイトル 任意の文字列
コマンド C:\Program Files (x86)\Microsoft Moles\bin\moles.runner.exe
引数 $(BinDir)/$(TargetName).exe /runner:"C:\Program Files (x86)\NUnit 2.6.2\bin\nunit-console.exe" /x86
初期ディレクトリ $(ProjectDir)
終了時にウィンドウを閉じる チェックを外す(結果を知りたいため)

実際の利用方法

実際には、以下のように利用します。
なお、コード例は neue cc - Rx + MolesによるC#での次世代非同期モックテスト考察 のものをNUnit用に一部改変しています。

1. Moles関連の参照の追加

参照設定の上で右クリック、Add Moles Assembly for mscorlib を選択します。
この状態でビルドを行い、必要な参照設定を自動的に追加しておきます。

2. NUnit関連の参照の追加

以下の2つを参照に追加します。

タブ 参照先
.NET nunit.framework
参照 上記でコピーした、Microsoft.Moles.NUnit.dllを選択
3. コードを書く

Molesまわりの設定を忘れずに行います。

  • usingでNUnit関連を2つほど指定
  • [assembly]の指定
  • テストメソッドに、[Moled]の指定


Molesでの置き換え方法については、MSTestの時と同じとなります。


以下、サンプルコードです。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;
using Microsoft.Moles.Framework.NUnit;


[assembly: Microsoft.Moles.Framework.MoledType(typeof(System.DateTime))]

namespace test
{    
    public class Production
    {
        // 現在時刻を元に"午前"か"午後"かを返すメソッド
        public string ImaDocchi()
        {
            return (DateTime.Now.Hour < 12) ? "午前" : "午後";
        }
    }

    [TestFixture]
    public class test1Test
    {
        [Test]
        [Moled]
        public void ImaDocchiのテスト()
        {
            Production sut = new Production();

            System.Moles.MDateTime.NowGet = () => new DateTime(2000, 1, 1, 5, 0, 0);
            Assert.That(sut.ImaDocchi(), Is.EqualTo("午前"));


            System.Moles.MDateTime.NowGet = () => new DateTime(2000, 1, 1, 15, 0, 0);
            Assert.That(sut.ImaDocchi(), Is.EqualTo("午後"));

            //  以下をアンコメントすると、エラー( = 正しく動作している)
            //Assert.That(sut.ImaDocchi(), Is.EqualTo("午前"));
        }
    }
}
4. テストを走らせる

VS2010に外部ツールの設定をしているため、、ツールより選択して実行すると、以下の結果が表示されます。

Microsoft Moles Runner v0.94.51023.0 -- http://research.microsoft.com/moles -- .
NET v4.0.30319
Copyright (c) Microsoft Corporation 2007-2010. All rights reserved.

restarting moles.runner in X86 mode... Microsoft Moles Runner v0.94.51023.0 -- h
ttp://research.microsoft.com/moles -- .NET v4.0.30319
Copyright (c) Microsoft Corporation 2007-2010. All rights reserved.

instrumenting...started
NUnit-Console version 2.6.2.12296
Copyright (C) 2002-2012 Charlie Poole.
Copyright (C) 2002-2004 James W. Newkirk, Michael C. Two, Alexei A. Vorontsov.
Copyright (C) 2000-2002 Philip Craig.
All Rights Reserved.

Runtime Environment -
OS Version: Microsoft Windows NT 6.1.7601 Service Pack 1
CLR Version: 4.0.30319.296 ( Net 4.0 )

ProcessModel: Default DomainUsage: Single
Execution Runtime: net-4.0
.
Tests run: 1, Errors: 0, Failures: 0, Inconclusive: 0, Time: 0.328 seconds
Not run: 0, Invalid: 0, Ignored: 0, Skipped: 0