Providing an `IEqualityComparer` for comparison
MiniKeb opened this issue · 1 comments
If I write a method that return an object with a type from a library, I can't add or modify the Equals()
method's of this type.
This imply that I won't be able to compare by value rather than by reference and my assertion will failed.
Expected Behavior
It would be nice if I could define my own IEqualityComparer
:
public class CustomComparer : IEqualityComparer<Item>
{
public bool Equals(Item x, Item y)
{
if (ReferenceEquals(null, x) || ReferenceEquals(null, y)) return false;
if (ReferenceEquals(x, y)) return true;
return x.Name == y.Name && x.Number == y.Number;
}
public int GetHashCode(Item obj)
{
return HashCode.Combine(obj.Name, obj.Number);
}
}
And use it in my test :
var items = sut.MyMethod(withParameter).ToArray();
var expected = new[]
{
new Item
{
Name = "ItemA",
Number = 111
},
new Item
{
Name = "ItemB",
Number = 222
}
};
Check.That(items).ContainsExactly(expected, new CustomComparer());
//OR
Check.RegisterEqualityComparer<Item>(new CustomComparer())
Check.That(items).ContainsExactly(expected);
Thanks for your feedback.
I have a working prototype that supports the register approach. As such, once a comparer is registered it is used for every relevant check.
Therefore you can also unregister it.
This looks like this:
Check.RegisterComparer<Item>(new CustomComparer());
Check.That(items).ContainsExactly(expected);
The recommended pattern is
try
{
var previous = Check.RegisterComparer<Item>(new CustomComparer());
Check.That(items).ContainsExactly(expected);
}
finally
{
// restore previous comparer
Check.RegisterComparer<Item>(previous);
}
Note that this feature requires some caching logic as searching for comparers will slow every test, so this requires extra work. But the feature will be available in the V3.0
expect a new beta in the coming days