我有一個類和用於此類,它實現一個IEqualityComparer
比較器:如何在IEqualityComparer上實現單元測試?
class Foo
{
public int Int { get; set; }
public string Str { get; set; }
public Foo(int i, string s)
{
Int = i;
Str = s;
}
private sealed class FooEqualityComparer : IEqualityComparer<Foo>
{
public bool Equals(Foo x, Foo y)
{
if (ReferenceEquals(x, y)) return true;
if (ReferenceEquals(x, null)) return false;
if (ReferenceEquals(y, null)) return false;
if (x.GetType() != y.GetType()) return false;
return x.Int == y.Int && string.Equals(x.Str, y.Str);
}
public int GetHashCode(Foo obj)
{
unchecked
{
return (obj.Int * 397)^(obj.Str != null ? obj.Str.GetHashCode() : 0);
}
}
}
public static IEqualityComparer<Foo> Comparer { get; } = new FooEqualityComparer();
}
兩種方法Equals
和GetHashCode
經由比較器的一個實例是用於例如List.Except
。
我的問題是:如何在這個比較器上正確實現單元測試?我想檢測是否有人在不修改比較器的情況下在Foo
中添加公共屬性,因爲在這種情況下,比較器將變爲無效。
如果我做這樣的事情:
Assert.That(new Foo(42, "answer"), Is.EqualTo(new Foo(42, "answer")));
這不能檢測到添加了新的屬性,這個屬性的兩個對象不同。
有沒有辦法做到這一點?
如果可能,我們可以添加一個屬性到一個屬性來說這個屬性在比較中是不相關的嗎?
你不能指望你的比較器比較不知道它們存在的屬性。您必須更改比較器以檢查新屬性。你可以通過使用反射來實現這一點,但這會讓你的比較器瘋狂地變慢。 – HimBromBeere
如果您打算將它用作哈希表中的鍵,那麼'Foo'應該是不可變的。在這種情況下,需要使用ctor的paramsters來設置新的屬性,並且任何這樣做的人都會看到您對Comparer的測試不再編譯。 (並希望更新比較器和測試)。 另一個簡單的方法,只需在Foo中添加一條評論,即比較者XXX需要更新。 – Magnus
@Magnus這似乎很有趣,但如何做到這一點? – Boiethios