web-dev-qa-db-ja.com

Moqモックオブジェクトをコンストラクタに渡す

RhinoMocksを長い間使用してきましたが、Moqを調べ始めました。私はこの非常に基本的な問題を抱えており、これが箱から出してすぐには飛ばないことに驚いています。次のクラス定義があるとします。

public class Foo
{
    private IBar _bar; 
    public Foo(IBar bar)
    {
        _bar = bar; 
    }
    ..
}

これで、Fooに送信するIBarをモックする必要があるテストがあります。 RhinoMocksでは、私は次のようにそれを行うだけで、うまくいきます:

var mock = MockRepository.GenerateMock<IBar>(); 
var foo = new Foo(mock); 

ただし、Moqでは、これは同じようには機能しないようです。私は次のようにしています:

var mock = new Mock<IBar>(); 
var foo = new Foo(mock); 

しかし、今は失敗します-「 'Moq.Mock'から 'IBar'に変換できません。何が問題なのですか?Moqでこれを行うための推奨される方法は何ですか?」

58
stiank81

あなたはモックのオブジェクトインスタンスを通過する必要があります

var mock = new Mock<IBar>();  
var foo = new Foo(mock.Object);

モックオブジェクトを使用して、インスタンスのメソッドにアクセスすることもできます。

mock.Object.GetFoo();

moq docs

99
skyfoot
var mock = new Mock<IBar>().Object
23

以前の答えは正しいですが、完全を期すために、もう1つ方法を追加したいと思います。 Linqライブラリのmoq機能を使用する。

public interface IBar
{
    int Bar(string s);

    int AnotherBar(int a);
}

public interface IFoo
{
    int Foo(string s);
}

public class FooClass : IFoo
{
    private readonly IBar _bar;

    public FooClass(IBar bar)
    {
        _bar = bar;
    }

    public int Foo(string s) 
        => _bar.Bar(s);

    public int AnotherFoo(int a) 
        => _bar.AnotherBar(a);
}

Mock.Of<T>と回避.Object呼び出し。

FooClass sut = new FooClass(Mock.Of<IBar>(m => m.Bar("Bar") == 2 && m.AnotherBar(1) == 3));
int r = sut.Foo("Bar"); //r should be 2
int r = sut.AnotherFoo(1); //r should be 3

またはマッチャーを使用する

FooClass sut = new FooClass(Mock.Of<IBar>(m => m.Bar(It.IsAny<string>()) == 2));
int r = sut.Foo("Bar"); // r should be 2
1
Johnny