使用精细的模拟框架 MoQ,我遇到了一个有点令人惊讶的方面(我不喜欢惊喜)。我正在模拟一个应该在方法调用之后添加到集合中的类,如下所示:
public class SomeClass{
}
public class Container {
private List<SomeClass> classes = new List<SomeClass>();
public IEnumerable<SomeClass> Classes {
get {
return classes;
}
}
public void addSomeClass(SomeClass instance) {
classes.Add(instance);
}
}
[Test]
public void ContainerContainsAddedClassAfterAdd() {
var mockSomeClass = new Mock<SomeClass>();
mockSomeClass.Setup(c => c.Equals(mockSomeClass.Object)).Return(true);
var Container = new Container();
Container.addSomeClass(mockSomeClass.Object);
Assert(Container.Classes.Contains(mockSomeClass.Object));
}
这很好用,mock 被添加到Container
's 集合中,Equals
mock 上的方法设置确保IEnumerable.Contains()
返回 true。然而,总是有一些复杂性。我真正嘲笑的课程并不像我们的SomeClass
. 是这样的:
public class SomeClassOverridingEquals{
public virtual Equals(SomeClassOverridingEquals other) {
return false;
}
public override Equals(object obj) {
var other = obj as SomeClassOverridingEquals;
if (other != null) return Equals(other); // calls the override
return false;
}
}
[Test]
public void ContainerContainsAddedClassOverridingEqualsAfterAdd() {
var mockSomeClass = new Mock<SomeClassOverridingEquals>();
mockSomeClass.Setup(c => c.Equals(mockSomeClass.Object)).Return(true);
var Container = new Container();
Container.addSomeClass(mockSomeClass.Object);
Assert(Container.Classes.Contains(mockSomeClass.Object)); // fails
}
该类包含对其自身特定类型的 Equals 方法的覆盖,并且Setup
模拟的方法似乎无法模拟出该特定方法(仅覆盖更通用的Equals(object)
)。因此测试失败。
到目前为止,除了重写类以不使用覆盖的等号之外,我还没有找到解决这种非常常见的模式的方法。
我不喜欢那样。
有人有想法么?