使用Moq模拟Func 构造函数参数并validation它是否被调用了两次

从这篇文章中获取问题( How to moq a Func )并对其进行了调整,因为答案不正确。

public class FooBar { private Func __fooBarProxyFactory; public FooBar(Func fooBarProxyFactory) { _fooBarProxyFactory = fooBarProxyFactory; } public void Process() { _fooBarProxyFactory(); _fooBarProxyFactory(); } } 

我需要模拟一个作为构造函数参数传递的Func ,断言func被调用两次。

当试图模拟函数var funcMock = new Mock<Func>(); 由于Func类型不可模拟,因此Moq引发exception。

问题是,如果没有模拟func,就不可能validation函数被调用(n)次。 funcMock.Verify( (), Times.AtLeast(2));

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

您可以自己创建一个普通的Func,返回一个IFooBarProxy的模拟:

 int numberOfCalls = 0; Func func = () => { ++numberOfCalls; return new Mock(); }; var sut = new FooBar(func); sut.Process(); Assert.Equal(2, numberOfCalls); 

至少从Moq 4.5.28开始,你可以像你期望的那样模拟和validationFunc。 我无法分辨这个function何时被添加(根据原始问题,在某些时候这不起作用)。

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

自Moq v4.1.1308.2120

在此问题被提出几个月后(2013年8月21日)发布的版本已经添加了模拟Func<>Func<> 。 因此,对于任何当前版本的mock,您可以使用var funcMock = new Mock>();

原始(过时)的答案

如果你有很多回调FuncActions等,最好在你的测试中定义一个帮助器接口并模拟该接口。 这样您就可以使用常规Moqfunction,例如设置返回值,测试输入参数等。

 interface IFooBarTestMethods { IFooBarProxy FooBarProxyFactory(); } 

用法

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