marklam
marklam

Reputation: 5358

How to add custom equality to NUnit while also keeping the default equality check

Is there a way to make a custom constraint such that NUnit's default equality test is done first, then the custom equality test?

For example, suppose I want to test that System.Double values are equal, but treat Double.PositiveInfinity as equal to Double.NegativeInfinity. I can write a simple test Comparison in the code below that checks this special case, then just uses ==.

Full code sample:

using System;
using NUnit.Framework;
using NUnit.Framework.Constraints;

namespace UnitTest
{
    [TestFixture]
    public class Class1
    {
        private Constraint IsKindaEqualTo(double expected)
        {
            // With this line, ShouldFail_NegativeInfinityIsKindaEqualTo7 reports "Expected: 7.0d or 7.0d But was:  ∞"
            return Is.EqualTo(expected).Or.EqualTo(expected).Using<double>((x, y) => Comparison(x, y));

            // With this line, the NaNisEqualToNaN test fails
            //return Is.EqualTo(expected).Using<double>((x, y) => Comparison(x, y));
        }

        private static bool Comparison(double x, double y)
        {
            if (Double.IsInfinity(x) && Double.IsInfinity(y))
            {
                return true;
            }
            else
            {
                return x == y;
            }
        }

        [Test]
        public void NegativeInfinityIsKindaEqualToPositiveInfinity()
        {
            var actual = Double.NegativeInfinity;
            var expected = Double.PositiveInfinity;

            Assert.That(actual, IsKindaEqualTo(expected));
        }

        [Test]
        public void ShouldFail_NegativeInfinityIsKindaEqualTo7()
        {
            var actual = Double.PositiveInfinity;
            var expected = 7.0;

            Assert.That(actual, IsKindaEqualTo(expected));
        }

        [Test]
        public void NaNisEqualToNaN()
        {
            var actual = Double.NaN;
            var expected = Double.NaN;

            Assert.That(actual, Is.EqualTo(expected));
        }

        [Test]
        public void NaNisKindaEqualToNan()
        {
            var actual = Double.NaN;
            var expected = Double.NaN;

            Assert.That(actual, IsKindaEqualTo(expected));
        }
    }
}

Upvotes: 1

Views: 431

Answers (1)

Chris
Chris

Reputation: 6042

NUnit's equality comparison comes from a class named NUnitEqualityComparer. I would create and use one of those inside your Comparison method, and wrap everything up in a single comparer. e.g:

    private static bool Comparison(double x, double y)
    {
        var nunitComparer = new NUnitEqualityComparer();
        if (nunitComparer.AreEqual(x,y)) return true;

        if (Double.IsInfinity(x) && Double.IsInfinity(y))
        {
            return true;
        }
        else
        {
            return x == y;
        }
    }

Upvotes: 1

Related Questions