如何为Func创建Moq模拟?

4
我有一个Func方法,我需要模拟它。
Func<Owned<ISomeInterface>> someMethod { get; set; }

但是我无法想出如何使用“Moq”框架进行模拟。

我已经阅读了类似的帖子,但仍然无法模拟成功,它总是返回

表达式不是方法调用:x => Invoke(x.someMethod )

或者

在模拟类型上未找到给定参数的匹配构造函数。 ----> System.MissingMethodException : 在类型“Owned`1Proxy40a9bf91815d4658ad2453298c903652”上未找到构造函数。


1
我已经在 Stack Overflow 上阅读了相关的帖子。 - user1049284
这是否意味着这个问题应该被关闭为重复?请澄清一下这个问题是否已经解决。 - MattDavey
1
抱歉,这篇文章似乎对我没有帮助,因为它对我没有用。我本来想编辑问题,但不小心添加了一个评论。我现在已经更新了问题。 - user1049284
为什么要模拟这个函数?这只是一个属性,你可以将其设置为满足签名的任何方法,然后调用它,不是吗? - Helikaon
@Helikaon,在我的情况下,我希望模拟一个序列,使得当多次调用该方法时返回不同的结果。我还想验证它被调用的次数。 - Doug Domeny
是的,但您可以完全控制委托方法的实现。如果(callCount == 1)返回value1; 如果(callCount == 2)返回value2; 并且您可以在测试中闭合一个本地callCount变量。 - Helikaon
1个回答

4
功能被定义为一个属性,所以您应该在Moq中使用SetupSet。
public interface IPersona
{
    string nome { get; set; }
    string cognome { get; set; }
    Func<Owned<ISomeInterface>> somemethod { get; set; }

}

在您的测试中:

您需要为Func创建一个模拟对象:

Func<Owned<ISomeInterface>> somemethodMock = () => new Mock<Owned<ISomeInterface>>().Object; 

接下来,您需要为包含Func属性的类设置模拟,并在Set方法上设置期望:

var obj = new Mock<IMyInterface>();
obj.SetupSet(x => x.somemethod = somemethodMock).Verifiable();

您需要创建模拟对象的容器对象:
```

您需要创建模拟对象的容器对象:

```
//We pass the mocked object to the constructor of the container class
var container = new Container(obj.Object);
container.AnotherMethod(somemethodMock);
obj.VerifyAll();

这里是容器类的另一种方法的定义,如果将get函数作为输入参数并将其设置为包含对象的属性

enter  public class Container
{
    private IPersona _persona;

    public Container(IPersona persona)
    {
        _persona = persona;
    }

    public void AnotherMethod(Func<MyClass<IMyInterface>> myFunc)
    {
        _persona.somemethod = myFunc;
    }      
}

1
谢谢,这似乎起作用了。现在我卡在代码的下一行了,哈哈,我需要从另一个程序集中调用一个静态方法...这会结束吗;-) - user1049284
真是痛苦啊 :) 看看这个:http://blogs.clariusconsulting.net/kzu/how-to-mock-extension-methods/ 它涵盖了扩展方法,但考虑到它们是静态的,应该适用,希望能有所帮助。 - Giorgio Minardi
1
AutofacContrib.Moq.dll允许您在模拟函数等方面做很多事情,似乎已经解决了问题。 - user1049284

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接