しばやん雑記

Azure とメイドさんが大好きなフリーランスのプログラマーのブログ

俺も Moq.dll を使ってみる

兄者はプロパティを中心に書いていたので、補足も兼ねて調べてみた。

モックを作る

Moq.Mock<T> クラスを使ってインスタンスを作ります。T はインターフェースでも抽象型でも構いません。

// Mock<T> を使う
var mock = new Mock<IFoo>();

プロパティを設定

Setup メソッドとラムダでプロパティを指定します。ここでは必ず false を返すようにします。

// bool IsFooBar { get; set; } というプロパティ
mock.Setup(p => p.IsFooBar).Returns(false);

メソッドを設定

メソッドもプロパティと同様に Setup とラムダでメソッドを指定します。ここでは必ず 10 を返すようにします。

// int Foo() というメソッド
mock.Setup(p => p.Foo()).Returns(10);

引数を取るメソッドを設定

Is.IsAny<T>() は引数の値は T 型なら何でもいいよという意味です。ここでは引数に関係なく常に 1 を返します。

// int Foo(int x, int y) というメソッド
mock.Setup(p => p.Foo(It.IsAny<int>(), It.AsAny<int>())).Returns(1);

引数を指定してメソッドを設定

引数の値を指定すると、指定された値の引数でメソッドが呼び出されたときの挙動だけを変えることが出来ます。

// int Foo(int x, int y) の引数が x = 1, y = 2 の時は 0 を返す
mock.Setup(p => p.Foo(1, 2)).Returns(0);

引数の条件を指定してメソッドを設定

It.Is<T>(Expression<Predicate<T>> match) メソッドは見たまんま引数の条件をラムダで指定します。

// int Foo(int x, int y) の引数が x が偶数, y は何でもの時は 100 を返す
mock.Setup(p => p.Foo(It.Is<int>(q => q % 2 == 0), It.IsAny<int>())).Returns(100);

引数の値を利用してメソッドを設定

Returns メソッドには 4 引数まで取るオーバーロードが用意されてるので、モックメソッドの引数の値を利用できます。

// int Foo(int x, int y) というメソッドで、x * y を返す
mock.Setup(p => p.Foo(It.IsAny<int>(), It.AsAny<int>())).Returns((int x, int y) => x * y);

Setup は条件を色々付けると定義順が結構重要になってくるので気をつけてください。