2013-02-06 43 views
18

从这篇文章中采纳了这个问题(How to moq a Func)并将其作为答案进行了修改,因为答案不正确。使用Moq来模拟Func <>构造函数参数并验证它被调用了两次

public class FooBar 
{ 
    private Func<IFooBarProxy> __fooBarProxyFactory; 

    public FooBar(Func<IFooBarProxy> fooBarProxyFactory) 
    { 
     _fooBarProxyFactory = fooBarProxyFactory; 
    } 

    public void Process() 
    { 
     _fooBarProxyFactory(); 
     _fooBarProxyFactory(); 
    } 
} 

我有一个需要模拟函数求<>被作为构造函数参数传递,该FUNC是调用两次断言。

当试图模拟功能var funcMock = new Mock<Func<IFooBarProxy>>(); Moq引发和异常,因为Func类型不可模仿。

问题是,如果不嘲笑函数,就不可能验证函数被调用了(n)次。 funcMock.Verify((), Times.AtLeast(2));

+0

Moq现在支持OP最初试图做的事情,请参阅@ ktam33的答案 – Mike

回答

27

我不认为有必要为Func使用模拟。

您可以简单地创建一个普通的函数功能自己返回的IFooBarProxy一个模拟:

int numberOfCalls = 0; 
Func<IFooBarProxy> func =() => { ++numberOfCalls; 
            return new Mock<IFooBarProxy>(); }; 

var sut = new FooBar(func); 

sut.Process(); 

Assert.Equal(2, numberOfCalls); 
2

由于起订量v4.1.1308.2120

由于这个版本,这是发布了一些个月后,这一问题被问(2013年8月21日),功能模拟Func<>has been added。因此,对于任何当前版本的模拟,您可以使用var funcMock = new Mock<Func<IFooBarProxy>>();

原件(过时)答案

如果你有很多回调Func的,Actions等,这是更好地定义你的测试一个助手接口和模拟该接口。这样,您就可以使用常规的起订量的功能,如设置了返回值,测试输入参数等

interface IFooBarTestMethods 
{ 
    IFooBarProxy FooBarProxyFactory(); 
} 

使用

var testMethodsMock = new Mock<IFooBarTestMethods>(); 
testMethodsMock 
    .Setup(x => x.FooBarProxyFactory()) 
    .Returns(new Mock<IFooBarProxy>()); 

var sut = new FooBar(testMethodsMock.Object.FooBarProxyFactory); 
testMethodsMock.Verify(x => x.FooBarProxyFactory(), Times.Exactly(2)); 
6

由于至少起订量4.5.28,你可以模拟并验证Func,就像你期望的那样。我无法分辨何时添加了此功能(根据原始问题,在某些时候这不起作用)。

[Test] 
public void TestFoobar() 
{ 
    var funcMock = new Mock<Func<IFooBarProxy>>(); 
    var fooBar = new FooBar(funcMock.Object); 
    fooBar.Process(); 
    funcMock.Verify(x => x(), Times.AtLeast(2)); 
}