我可以使用 NUnit 的 EqualTo().Using() 来比较不同类型的对象吗?
Can I compare objects of different types using NUnit's EqualTo().Using()?
我希望能够使用 NUnit 的 Assert.That
比较 IConvertible
和 DateTime
中的任何两个事物,最好不要创建自定义约束。我有一个简单的 IComparer
可以很好地解决问题。它适用于 EqualTo().Using()
、,只要实际和预期的类型相同 。看起来 EqualsConstraint
的 AdjustArgumentIfNeeded
方法在我的 IComparer
开始工作之前断言失败了。
如果 actual 和 expected 可以转换为相同的日期时间,我该怎么做才能让 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
方法在两个通过的情况下进入,在两个失败的情况下没有进入。
这是一个您必须在 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;
}
如果参数都是字符串或都不是字符串,则此 returns 为真,但如果一个是字符串而另一个不是(字符串是一个 IEnumerable,通过 IEnumerable<char>
)。如果 CanCompare returns false 它甚至不会进入您的自定义比较器以查看参数是否相等并且框架将 运行 默认比较逻辑。我不认为 CanCompare 在与任何基本 Using(IComparer)
类型约束一起使用时会被覆盖。
经过进一步调查,我发现正确的行为已经实现,只是不在默认 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);
}
}
我希望能够使用 NUnit 的 Assert.That
比较 IConvertible
和 DateTime
中的任何两个事物,最好不要创建自定义约束。我有一个简单的 IComparer
可以很好地解决问题。它适用于 EqualTo().Using()
、,只要实际和预期的类型相同 。看起来 EqualsConstraint
的 AdjustArgumentIfNeeded
方法在我的 IComparer
开始工作之前断言失败了。
如果 actual 和 expected 可以转换为相同的日期时间,我该怎么做才能让 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
方法在两个通过的情况下进入,在两个失败的情况下没有进入。
这是一个您必须在 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;
}
如果参数都是字符串或都不是字符串,则此 returns 为真,但如果一个是字符串而另一个不是(字符串是一个 IEnumerable,通过 IEnumerable<char>
)。如果 CanCompare returns false 它甚至不会进入您的自定义比较器以查看参数是否相等并且框架将 运行 默认比较逻辑。我不认为 CanCompare 在与任何基本 Using(IComparer)
类型约束一起使用时会被覆盖。
经过进一步调查,我发现正确的行为已经实现,只是不在默认 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);
}
}