Работая с прекрасным mocking-framework 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));
}
Это работает хорошо, макет добавляется в коллекцию Container
, а настройка метода Equals
на макете гарантирует, что IEnumerable.Contains()
вернет истину. Однако всегда есть сложности. Класс, над которым я насмехаюсь, не так прост, как наш 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)
). Таким образом, тест не проходит.
Я до сих пор не нашел способа обойти этот довольно распространенный шаблон, кроме как переписать класс, чтобы не использовать переопределяющие равенства.
Мне это не нравится.
У кого-нибудь есть идеи?