我可以使用NUnit的EqualTo()来比较不同类型的对象。使用()?

时间:2016-08-02 03:25:12

标签: c# nunit icomparer

我希望能够使用NUnit' IConvertibleDateTimeAssert.That的任何两件事进行比较,最好不要创建自定义约束。我有一个简单的IComparer可以很好地完成这个伎俩。它适用于EqualTo().Using(),只要实际和预期属于同一类型。在EqualsConstraint完成工作之前,AdjustArgumentIfNeeded IComparer方法看起来失败了。

如果实际和预期可以转换为相同的日期时间,那么我可以做什么来允许Assert.That(actual, Is.EqualTo(expected).Using(DateTimeComparer.Instance));形式的任何测试通过,否则会失败?

这是一个MCVE,它显示了当我比较从不同格式字符串转换的日期时传递的两个测试,但在将转换日期与实际DateTime进行比较时失败。

using NUnit.Framework;
namespace NunitTest
{
    public class DateTimeComparer : IComparer
    {
        public static readonly DateTimeComparer Instance = new DateTimeComparer();

        public int Compare(object x, object y)
        {
                var dateTime1 = Convert.ToDateTime(x);
                var dateTime2 = Convert.ToDateTime(y);
                return dateTime1.CompareTo(dateTime2);
        }
    }

    [TestFixture]
    public class DateTimeComparerTest
    {
        [Test]
        public void TestComparerUsingString()
        {
            // Passes
            Assert.That("2 August 2016",
                        Is.EqualTo("02/08/2016")
                          .Using(DateTimeComparer.Instance));
        }

        [Test]
        public void TestComparerUsingDateTime()
        {
            // Passes
            Assert.That(new DateTime(2016, 8, 2),
                        Is.EqualTo(new DateTime(2016, 8, 2))
                          .Using(DateTimeComparer.Instance));
        }

        [Test]
        public void TestComparerUsingExpectedDateTime()
        {
            // Fails
            Assert.That("2 August 2016",
                        Is.EqualTo(new DateTime(2016, 8, 2))
                          .Using(DateTimeComparer.Instance));
        }

        [Test]
        public void TestComparerUsingActualDateTime()
        {
            // Fails
            Assert.That(new DateTime(2016, 8, 2),
                        Is.EqualTo("2 August 2016")
                          .Using(DateTimeComparer.Instance));
        }
    }
}

调试显示在两个通过案例中输入了Compare方法,并且未在两个失败案例中输入。

2 个答案:

答案 0 :(得分:1)

这是您必须在NUnit中提交以完全解决的问题。我相信观察到的行为的原因可以在CanCompare方法的EqualityAdapter.cs中找到:

public virtual bool CanCompare(object x, object y)
{
    if (x is string && y is string)
        return true;

    if (x is IEnumerable || y is IEnumerable)
        return false;

    return true;
}

如果参数既是字符串又不是字符串,则返回true,但如果一个是字符串而另一个不是字符串,则返回true(字符串是通过IEnumerable<char>的IEnumerable)。如果CanCompare返回false,它甚至不会进入自定义比较器以查看参数是否相等,框架将运行默认比较逻辑。我不相信CanCompare在与任何基本Using(IComparer)类型约束一起使用时会被覆盖。

答案 1 :(得分:1)

经过进一步调查后,我发现已经实施了正确的行为,而不是默认的EqualityAdapter。使用任何通用适配器都可以。也就是说,将问题中的比较器更改为此会使测试通过:

public class DateTimeComparer : IComparer<IConvertible>
{
    public static readonly DateTimeComparer Instance = new DateTimeComparer();

    public int Compare(IConvertible x, IConvertible y)
    {
        var dateTime1 = Convert.ToDateTime(x);
        var dateTime2 = Convert.ToDateTime(y);
        return dateTime1.CompareTo(dateTime2);
    }
}