我有一个有趣的问题要解决。考虑像这样的一些接口(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;
}
事情是这样的。上面的代码在没有警告的情况下编译,但永远不会工作。 Moq
为 Equals()
创建拦截器方法,但从未达到。相反,调用对象代理的 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/