優れたモッキングフレームワーク 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()
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)
です)。したがって、テストは失敗します。
これまでのところ、オーバーライドする equals を使用しないようにクラスを書き直す以外に、この非常に一般的なパターンに対処する方法を見つけていません。
私はそれが好きではありません。
誰にもアイデアはありますか?