← Back to team overview

nunit-core team mailing list archive

[Bug 1157828] [NEW] EqualityComparer does not respect value-equality for null

 

Public bug reported:

I am using a third-party library that includes Null Objects with value
comparisons that return true for null.  However, the NUnit equality
comparer uses reference equality (via the == operator with System.Object
references) to check for null and returns false if only one input is the
null pointer.  This means that the value-equality comparison for the
custom type is never reached.

The following is a quick & dirty implementation of a Null Object with a
few tests that demonstrate the problem:

public class MyObject
{
    public static MyObject NullObject = new MyObject(-1);

    public int Value { get; set; }

    public MyObject(int value)
    {
        this.Value = value;
    }

    public static bool operator ==(MyObject left, MyObject right)
    {
        if (ReferenceEquals(left, NullObject) || ReferenceEquals(left, null))
            return (ReferenceEquals(right, NullObject) || ReferenceEquals(right, null));

        else if (ReferenceEquals(right, NullObject) || ReferenceEquals(right, null))
            return false;

        return Equals(left, right);
    }

    public static bool operator !=(MyObject left, MyObject right)
    {
        return !(left == right);
    }
    public override bool Equals(object obj)
    {
        if (ReferenceEquals(obj, NullObject) || ReferenceEquals(obj, null))
            return (ReferenceEquals(this, NullObject));

        else if (ReferenceEquals(this, NullObject))
            return false;

        MyObject myobj = obj as MyObject;
        if (myobj == null)
            return false;

        return this.Value == myobj.Value;
    }

    public override int GetHashCode()
    {
        return base.GetHashCode();
    }

}

[TestFixture]
public class TestNullObject
{
    // TEST PASSES
    [Test]
    public void TestIsTrue()
    {
        Assert.IsTrue(MyObject.NullObject == null);
        Assert.IsTrue(null == MyObject.NullObject);
    }

    // TESTS FAIL
    [Test]
    public void TestIsNull()
    {
        Assert.IsNull(MyObject.NullObject);
    }

    [Test]
    public void TestAreEqual1()
    {
        Assert.AreEqual(MyObject.NullObject, null);
    }

    [Test]
    public void TestAreEqual2()
    {
        Assert.AreEqual(null, MyObject.NullObject);
    }
}

** Affects: nunitv2
     Importance: Undecided
         Status: New

-- 
You received this bug notification because you are a member of NUnit
Developers, which is subscribed to NUnit V2.
https://bugs.launchpad.net/bugs/1157828

Title:
  EqualityComparer does not respect value-equality for null

Status in NUnit V2 Test Framework:
  New

Bug description:
  I am using a third-party library that includes Null Objects with value
  comparisons that return true for null.  However, the NUnit equality
  comparer uses reference equality (via the == operator with
  System.Object references) to check for null and returns false if only
  one input is the null pointer.  This means that the value-equality
  comparison for the custom type is never reached.

  The following is a quick & dirty implementation of a Null Object with
  a few tests that demonstrate the problem:

  public class MyObject
  {
      public static MyObject NullObject = new MyObject(-1);

      public int Value { get; set; }

      public MyObject(int value)
      {
          this.Value = value;
      }

      public static bool operator ==(MyObject left, MyObject right)
      {
          if (ReferenceEquals(left, NullObject) || ReferenceEquals(left, null))
              return (ReferenceEquals(right, NullObject) || ReferenceEquals(right, null));

          else if (ReferenceEquals(right, NullObject) || ReferenceEquals(right, null))
              return false;

          return Equals(left, right);
      }

      public static bool operator !=(MyObject left, MyObject right)
      {
          return !(left == right);
      }
      public override bool Equals(object obj)
      {
          if (ReferenceEquals(obj, NullObject) || ReferenceEquals(obj, null))
              return (ReferenceEquals(this, NullObject));

          else if (ReferenceEquals(this, NullObject))
              return false;

          MyObject myobj = obj as MyObject;
          if (myobj == null)
              return false;

          return this.Value == myobj.Value;
      }

      public override int GetHashCode()
      {
          return base.GetHashCode();
      }

  }

  [TestFixture]
  public class TestNullObject
  {
      // TEST PASSES
      [Test]
      public void TestIsTrue()
      {
          Assert.IsTrue(MyObject.NullObject == null);
          Assert.IsTrue(null == MyObject.NullObject);
      }

      // TESTS FAIL
      [Test]
      public void TestIsNull()
      {
          Assert.IsNull(MyObject.NullObject);
      }

      [Test]
      public void TestAreEqual1()
      {
          Assert.AreEqual(MyObject.NullObject, null);
      }

      [Test]
      public void TestAreEqual2()
      {
          Assert.AreEqual(null, MyObject.NullObject);
      }
  }

To manage notifications about this bug go to:
https://bugs.launchpad.net/nunitv2/+bug/1157828/+subscriptions


Follow ups

References