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)でも使えるようになることを祈ります。
環境
- Windows7 x64
- Visual Studio 2010 SP1 (以下、VS2010)
- NUnit 2.6.2
- Moles 0.94.51023.0
セットアップ
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を使ったテストはNUnitのGUIテストランナーでは動作しません。
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