从本文(How to moq a Func)中提取问题并对其进行调整,因为答案不正确。
public class FooBar
{
private Func<IFooBarProxy> __fooBarProxyFactory;
public FooBar(Func<IFooBarProxy> fooBarProxyFactory)
{
_fooBarProxyFactory = fooBarProxyFactory;
}
public void Process()
{
_fooBarProxyFactory();
_fooBarProxyFactory();
}
}
我需要模拟一个Func&lt;&gt;作为构造函数参数传递,断言func被调用两次。
当试图模拟函数var funcMock = new Mock<Func<IFooBarProxy>>();
时Moq引发异常,因为Func类型不可模拟。
问题在于,如果没有模拟func,就无法验证函数是否被调用(n)次。 funcMock.Verify( (), Times.AtLeast(2));
答案 0 :(得分:32)
我认为没有必要为Func使用模拟。
您可以自己创建一个普通的Func,返回模拟IFooBarProxy
:
int numberOfCalls = 0;
Func<IFooBarProxy> func = () => { ++numberOfCalls;
return new Mock<IFooBarProxy>(); };
var sut = new FooBar(func);
sut.Process();
Assert.Equal(2, numberOfCalls);
答案 1 :(得分:19)
至少从Moq 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));
}
答案 2 :(得分:4)
自Moq v4.1.1308.2120
以来此版本是在问题被提出几个月后发布的(2013年8月21日),模拟Func<>
has been added的功能。因此,对于任何当前版本的模拟,您可以使用var funcMock = new Mock<Func<IFooBarProxy>>();
。
原创(过时)回答
如果您有很多回调Func
,Actions
等,最好在测试中定义帮助程序界面并模拟该界面。这样您就可以使用常规Moq功能,例如设置返回值,测试输入参数等等。
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));