Using NUnit 2.5.9, the following test unexpectedly fails:
[TestFixture]
public class FooTest
{
[Test]
public void Inequality()
{
var first = new Foo(new[] { 1 }, 2);
var second = new Foo(new[] { 1 }, 3);
Assert.AreNotEqual(first, second);
}
}
public struct Foo : IEnumerable<int>, IEquatable<Foo>
{
private readonly IEnumerable<int> values;
public int Bar { get; private set; }
public Foo(IEnumerable<int> values, int bar)
: this()
{
this.values = values;
Bar = bar;
}
public IEnumerator<int> GetEnumerator()
{
return values.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
public bool Equals(Foo other)
{
return other.values.SequenceEqual(values) && other.Bar == Bar;
}
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj))
{
return false;
}
if (obj.GetType() != typeof(Foo))
{
return false;
}
return Equals((Foo)obj);
}
public override int GetHashCode()
{
unchecked
{
return ((values != null ? values.GetHashCode() : 0) * 397) ^ Bar;
}
}
public static bool operator ==(Foo left, Foo right)
{
return left.Equals(right);
}
public static bool operator !=(Foo left, Foo right)
{
return !left.Equals(right);
}
}
Digging into the NUnit code, it turns out that when NUnit encounters two objects that implement IEnumerable, it just compares the two collections and ignores any other properties on the objects.
This feels wrong to me: the fact that an object implements a particular interface does not limit it to only performing that role. Or is the IEnumerable interface in .NET a special case? Or have I just misunderstood NUnit?
Looks like this is a bug in NUnit, as far as I understand it would be fixed in 3.0 version. Below some discussion with a possible work around implementing IComparer<T>
:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With