nunit-core team mailing list archive
-
nunit-core team
-
Mailing list archive
-
Message #03446
[Bug 1157828] Re: EqualityComparer does not respect value-equality for null
I think the biggest reason to fix it would be for consistency. Right
now, if you override the equality operation, it will use the custom
comparison EXCEPT for the case where one side is null. That means that
you would essentially need to document the Assert.AreEqual method to say
that it uses the custom comparison for types that override
Object::Equals but performs a reference comparison when 'actual' or
'expected' is null. As an API developer, this sounds like a
documentation nightmare. And since most programmers aren't inclined to
read the documentation anyway, once they see that it uses their custom
implementation once, they will assume that it always uses the custom
implementation.
I'm not thrilled with the NullObject API I'm using, but its
documentation recommends using 'resultObj != null' as the null check
even in cases where the NullObject might be returned. Having written
'if (resultObje != null)' all over production code, I instinctively
wrote 'Assert.IsNotNull(resultObj)' in my test code. Only to have them
fail unexpectedly later on when trying to perform an unsupported
operation on the NullObject. I can completely back the idea that IsNull
and IsNotNull should be reference comparisons to the null pointer, but
with the same Equality logic underneath, it is closely coupled to the
AreEqual ambiguity.
Chances are that a caller isn't going to test every particular
circumstance. If I have a type that overrides .Equals, I would run a
quick test to see if something like AreEqual is using reference
comparison or calling my custom comparison. After that first check I
would assume (never a good idea, but not uncommon) that the method will
always use the custom comparison.
And evidence indicates that at least one otherwise talented developer
has fallen into this trap already! ;)
--
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
References