简体   繁体   English

模拟使用Moq扩展另一个接口的接口

[英]Mocking an interface that extends another interface using Moq

Hej Buddies! Hej好友!

I'm trying to create a mock for an interface like the one below: 我正在尝试为类似下面的界面创建一个模拟:

public interface ITheInterface: IEnumerable
{
...
}

In these manners: 通过以下方式:

var theInterfaceMock = new Mock<ITheInterface>();
theInterfaceMock.Setup(x => x.OfType<SomeType>()).Returns(something);

and

var theInterfaceMock = new Mock<ITheInterface>();
theInterfaceMock.As<IEnumerable>();
theInterfaceMock.Setup(x => x.OfType<SomeType>()).Returns(something);

And in both cases I'm getting a System.NotSupportedException that basically tells me that that ITheInterface doesn't have the OfType() method (when it actually does have it). 在这两种情况下,我都得到一个System.NotSupportedException,它基本上告诉我ITheInterface不具有OfType()方法(实际上确实具有)。 Anybody knows any way to solve this issue?. 有人知道解决此问题的方法吗?

Thank you! 谢谢!

OfType is not a method on the IEnumerable, it's an extension method called Enumberable.OfType . OfType不是IEnumerable上的方法, 它是称为Enumberable.OfType的扩展方法

This is why Moq is complaining I think. 我想这就是Moq抱怨的原因。 Since these are static classes, I think you'll need to use a tool like typemock . 由于这些是静态类,因此我认为您需要使用诸如typemock之类的工具。

Question is however. 问题是。 Why you need to mock OfType()? 为什么需要模拟OfType()? You can trust that the microsoft implementation of Enumberable.OfType works. 您可以相信Enumberable.OfType的Microsoft实现是有效的。 So just mock the the IEnumberable interface (GetEnumerator) , and return a mock that support IEnumerator, that OfType will use. 因此,只需模拟IEnumberable接口(GetEnumerator) ,然后返回支持OfType将使用的IEnumerator的模拟。

IEnumerable has no method named OfType ... are you looking for IEnumerable? IEnumerable没有名为OfType的方法...您是否在寻找IEnumerable? - Even there OfType is just an extension method and you would have to mock the Enumerable-class and it's static members. -即使OfOf仅仅是扩展方法 ,您也必须模拟Enumerable-class及其静态成员。 I don't think Moq can do this - sorry. 我认为Moq无法做到这一点-抱歉。

Here are some related questions (with possible workarounds): How do I use Moq to mock an extension method? 以下是一些相关的问题(可能的解决方法): 如何使用Moq模拟扩展方法? and Mock static property with moq moq模拟静态属性

I believe the issue here is that OfType is an extension method. 我相信这里的问题是OfType是扩展方法。 Since Moq (and other mocking frameworks) work by creating proxy objects/classes of the interfaces being mocked, it only has the ability to mock instance methods. 由于Moq(和其他模拟框架)通过创建要模拟的接口的代理对象/类来工作,因此它仅具有模拟实例方法的能力。 Extension methods are just static methods in disguise. 扩展方法只是伪装的静态方法。

As other already told OfType is not a method of the IEnumerable interface. 正如其他已经讲过的,OfType不是IEnumerable接口的方法。 However, you don't really need to mock it, all you need is to mock IEnumerable.GetEnumerator method which is pretty easy to do: 但是,您实际上并不需要模拟它,您只需要模拟IEnumerable.GetEnumerator方法即可,它很容易做到:


    var enumerable = new Mock<IEnumerable>();
    var something = new List<SomeType>
    {
        new SomeType(),
        new SomeType(),
        new SomeType(),
    };
    enumerable.Setup(_ => _.GetEnumerator()).Returns(something.GetEnumerator());

    Assert.That(enumerable.Object.OfType<SomeType>(), Is.EquivalentTo(something));

You just forward GetEnumerator method to one of the 'something' collection and that is all. 您只需将GetEnumerator方法转发到“某物”集合之一即可,仅此而已。 You'll get all extension methods working for your mock automatically. 您将自动获得适用于您的模拟的所有扩展方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM