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

本文关键字:构造函数 对象 Moq 模拟 | 更新日期: 2023-09-27 18:04:57

我已经使用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转换。模仿'到'IBar'。我做错了什么?Moq的推荐方法是什么?

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

您需要传递mock的对象实例

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

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

mock.Object.GetFoo();

moq文档

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

前面的答案都是正确的,但为了完整起见,我想再加一条。利用moq库的Linq特性。

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