【C#】【Mock】Moq ~ 文法編 ~

■ Mockインスタンス作成とMockオブジェクト取得

構文

// テストしたいクラスのモックオブジェクトを作成
Mock<対象とするインターフェイス・クラス> mock = new Mock<対象とするインターフェイス・クラス>();
mock.Setup(m => m.テストしたいメソッド名(パラメータ)).Returns(理想の戻り値);

// Mockオブジェクト取得
var obj = mock.Object;

■ 対象インターフェイスの期待値を設定

構文

Setup(x => x.メソッド(引数)).Returns(戻り値);

サンプル

// Sum()が第一引数「1」、第二引数「2」で呼ばれたら「3」を返すように設定
mock.Setup(x => x.Sum(1, 2)).Returns(3);

// Sum()が第一引数「6」、第二引数「5」で呼ばれたら「11」を返すように設定
int num1 = 11;
this.mock.Setup(x => x.Sum(6, 5)).Returns(num1);

// Sum()が第一引数「6」、第二引数「0」で呼ばれたら「6」を返すように設定
int num2 = 6;
this.mock.Setup(x => x.Sum(6, 0)).Returns(() => num2);

■ Verify() / VerifyAll()

 モックが意図した通りに呼び出されたかどうかを確認する。
Verify()またはVerifyAll()で指定した以外にモックが実装されてた場合はエラーが発生する。
http://journal.mycom.co.jp/articles/2009/06/15/moq/001.html
の解説、分かりやすい。
http://dotnetlogbook.blogspot.com/2009/09/30.html
も頭に入れておこ。

構文

mock.Verify();

mock.Verify(引数)

サンプル

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

// Sum(5, 5)が呼び出されたかを確認。(呼び出されてなければ、エラー発生)
mock.Verify(x => x.Sum(5, 5));
// 一回だけが呼び出されたかを確認。(一回以外呼び出された場合(0回や2回など)、エラー発生)
mock.Verify(x => x.Sum(5, 5), Times.Once());

■ AtMostOnce()とAtMost(n)

 * AtMostOnce()は、メソッドの呼び出し回数を1回に制限する(2回目以降の呼び出しはエラー)
 * AtMost(n)は、n+1回目からエラー

構文

Setup(x => x.メソッド(引数)).Returns(戻り値).AtMostOnce();

Setup(x => x.メソッド(引数)).Returns(戻り値).AtMost(回数);

サンプル

// Sum()が第一引数「4」、第二引数「3」で呼ばれたら「7」を返すように設定
// 1回だけ呼び出し可能
this.mock.Setup(m => m.Sum(4, 3)).Returns(7).AtMostOnce();

// Sum()が第一引数「7」、第二引数「2」で呼ばれたら「9」を返すように設定
// 2回だけ呼び出し可能(1回もOK、3回目からエラー)
this.mock.Setup(m => m.Sum(7, 2)).Returns(9).AtMost(2);

■ Throws()

 * Throws()は、例外を設定可能。指定したメソッドを呼び出した時に例外が発生する。

構文

Setup(x => x.メソッド(引数)).Returns(戻り値).Throws<例外>();

Setup(x => x.メソッド(引数)).Returns(戻り値).Throws(new 例外());

サンプル

// Sum()が第一引数「2」、第二引数「2」で呼ばれたら例外を返すように設定
this.mock.Setup(m => m.Sum(2, 2)).Throws<ArgumentException>();

// Sum()が第一引数「3」、第二引数「3」で呼ばれたら例外を返すように設定
this.mock.Setup(m => m.Sum(3, 3)).Throws(new ArgumentException());

■ Callback()

 * Callback()は、任意の処理を実行する。
   メソッド呼び出しのタイミングで、ログを出力するなどに使える

構文

Setup(x => x.メソッド(引数)).Returns(戻り値).Callback((引数) => 【任意の処理】);

Setup(x => x.メソッド(引数)).Returns(戻り値).Callback<引数>((引数) => 【任意の処理】);

サンプル

// Sum()が第一引数「4」、第二引数「4」で呼ばれたら「8」を返すように設定
this.mock.Setup(x => x.Sum(4, 4)).Returns(8).Callback((int x, int y) => Console.WriteLine(x + y));
// Sum()が第一引数「6」、第二引数「7」で呼ばれたら「13」を返すように設定
this.mock.Setup(x => x.Sum(6, 7)).Returns(13).Callback<int, int>((x, y) => Console.WriteLine(x + y));

// Sum()が第一引数「4」、第二引数「4」で呼ぶ
// (NUnitの「Test outout」タブに「8」と出力される)
Assert.AreEqual(8, obj.Sum(4, 4));
// Sum()が第一引数「6」、第二引数「7」で呼ぶ
Assert.AreEqual(13, obj.Sum(6, 7));

■ 引数なんでもあり

 * It.IsAny()は、引数が何でも良い場合に使用

構文

Setup(x => x.メソッド(It.IsAny<引数の型>())).Returns(戻り値);

サンプル

// Sum(引数が何でも良い)で呼ばれたら「10」を返すように設定
this.mock.Setup(x => x.Max(It.IsAny<int>(), It.IsAny<int>())).Returns(10);

// Sum()が第一引数「6」、第二引数「7」で呼ぶ
Assert.AreEqual(10, obj.Sum(6, 7));

■ 初期化

構文

[SetUp] // テストコードの初期化のために[SetUp]属性をメソッドにつける
public void SetUp()
{
   // 初期化
}


関連記事

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