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

C# 将Moq模拟对象传递给构造函数,c#,.net,mocking,moq,C#,.net,Mocking,Moq,我已经使用Rhinomock很长一段时间了,但刚刚开始研究Moq。我有一个非常基本的问题,让我惊讶的是,这个问题并没有完全解决。假设我有以下类定义: public class Foo { private IBar _bar; public Foo(IBar bar) { _bar = bar; } .. } 现在我有一个测试,需要模拟发送给Foo的IBar。在Rhinomock中,我只需按照以下方式进行操作,而且效果非常好: var

我已经使用Rhinomock很长一段时间了,但刚刚开始研究Moq。我有一个非常基本的问题,让我惊讶的是,这个问题并没有完全解决。假设我有以下类定义:

public class Foo
{
    private IBar _bar; 
    public Foo(IBar bar)
    {
        _bar = bar; 
    }
    ..
}
现在我有一个测试,需要模拟发送给Foo的IBar。在Rhinomock中,我只需按照以下方式进行操作,而且效果非常好:

var mock = MockRepository.GenerateMock<IBar>(); 
var foo = new Foo(mock); 
var mock=MockRepository.GenerateMock();
var foo=新foo(模拟);
然而,在Moq中,这似乎不是以同样的方式工作。我的工作如下:

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

但是,现在它失败了-告诉我“无法从'Moq.Mock'转换为'IBar'。我做错了什么?建议使用Moq执行此操作的方法是什么?

您需要通过Mock的对象实例

var mock = new Mock<IBar>();  
var foo = new Foo(mock.Object);
var mock=new mock().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
并避免调用
.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=newfooclass(Mock.Of(m=>m.Bar(“Bar”)==2和&m.AnotherBar(1)==3));
int r=sut.Foo(“Bar”);//r应该是2
int r=sut.AnotherFoo(1);//r应该是3
或者使用匹配器

FooClass sut = new FooClass(Mock.Of<IBar>(m => m.Bar(It.IsAny<string>()) == 2));
int r = sut.Foo("Bar"); // r should be 2
fooclassut=newfooclass(Mock.Of(m=>m.Bar(It.IsAny())==2));
int r=sut.Foo(“Bar”);//r应该是2

+1因为只落后于将被接受的答案10秒。Thx!我通常不会将对象实例分配给这样的变量,因为您可能希望为特定行为设置模拟。这只是为了显示.object,这是他所遇到的运行时错误的解决方案:-)我如何指定几个方法/参数I在模拟定义中?类似于
newfooclass(Mock.Of(m=>m.Bar(“Bar”)==2,k=>k.Ready()==true));
@ulkas你应该使用
&&
,我已经更新了答案,
FooClass(Mock.Of(m=>m.Bar(“Bar”)==2&&m.Ready()=true))
但是我需要
mock.Object
只有在我调用
foo.Object
时才能初始化。我基本上想要的是能够传递给
foo
的构造函数,即原始的
mock
,在我调用
mock.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