将Moq模拟对象传递给构造函数

时间:2011-08-10 13:29:08

标签: c# .net mocking 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建议的方法是什么?

3 个答案:

答案 0 :(得分:98)

您需要通过模拟

的对象实例
var mock = new Mock<IBar>();  
var foo = new Foo(mock.Object);

您还可以使用模拟对象来访问实例的方法。

mock.Object.GetFoo();

moq docs

答案 1 :(得分:23)

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

答案 2 :(得分: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