Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Incorrect behaviour of NUnit Assert.AreNotEqual when dealing with IEnumerable<T>?

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?

like image 393
Akash Avatar asked Oct 24 '22 10:10

Akash


1 Answers

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>:

  • Equality constraints and IEnumerable confusion
  • NUNit bug tracker: Use overridden Equals for IEnumerables, Collections, etc.
like image 91
sll Avatar answered Nov 15 '22 12:11

sll