c# - 如何使用 Moq 为接口(interface)模拟 `object.Equals(object obj)`

标签 c# .net moq

我有一个有趣的问题要解决。考虑像这样的一些接口(interface):

public interface IMyThing
{
    int Id { get; }
}

现在我想测试使用这个接口(interface)的代码。也许有一些 LINQ 魔法。像这样:

public class SomeClass
{
    private IMyThing _thing;

    ...

    public bool HasThing(IEnumerable<IMyThing> things)
    {
        return things.Contains(_thing);
    }
}

我正在模拟所有实现 IMyThing 的对象使用 Moq :

public static IMyThing MockMyThing(int newId)
{
    var mock = new Mock<IMyThing>();
    mock.Setup(s => s.Id).Returns(newId);
    mock.Setup(s => s.Equals(It.IsAny<object>())).Returns<object>(obj =>
    {
        if (typeof(IMyThing).IsAssignableFrom(obj.GetType()))
        {
            return ((IMyThing)obj).Id == newId;
        }

        return false;
    });

    return mock.Object;
}

事情是这样的。上面的代码在没有警告的情况下编译,但永远不会工作。 MoqEquals() 创建拦截器方法,但从未达到。相反,调用对象代理的 equals 方法。我在指责我在模拟一个接口(interface)而不是一个具体的类。

更新: 刚刚意识到 Moq甚至不创建拦截器。

当然我可以增加 IMyThing界面是这样的:

public interface IMyThing : IEquatable<IMyThing>
{
    int Id { get; }
}

LINQ 运算符会识别 IEquatable<T>界面并使用它。

我不想这样做是因为:

  • 这只能与其他 IMyThing 一起使用对象
  • IEquatable<T>不是为了这个目的
  • 我不想为了让它变得可 mock 而污染我的模型

你会如何解决这个问题?

最佳答案

我最终为 Github 上的 Moq 项目贡献了代码(参见 issue #248 )。通过此更改,可以模拟 object.Equals(object obj)object.GetHashCode()object.ToString(),甚至用于界面模拟。

让我们看看它是否被接受。

关于c# - 如何使用 Moq 为接口(interface)模拟 `object.Equals(object obj)`,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35406423/

相关文章:

c# - 有没有办法轻松解析可移植类库中的文件路径?

c# - 使用 C#/Moq 框架模拟带有输入参数的异步 DbContext 函数

c# - 为 EF dbcontext 设置模拟对象以测试存储库方法

c# - 如何使用 Moq stub 接口(interface)方法

c#动态行为?

.net - Azure 应用服务容器不断重新启动 - "Container failed availability check."

c# - 过滤器表达式的类设计

c# - 在 Orchard CMS 中使用 Document.cshtml 的替代品

c# - 我可以告诉 NHibernate 不要保存某些对象吗?

c# - WPF ComboBox 中带有列的不可选择的标题