C# 我可以使用NUnit';比较不同类型的对象吗;s EqualTo()。是否使用()?
我希望能够使用NUnit的C# 我可以使用NUnit';比较不同类型的对象吗;s EqualTo()。是否使用()?,c#,nunit,icomparer,C#,Nunit,Icomparer,我希望能够使用NUnit的Assert将IConvertible与DateTime中的任意两个内容进行比较。这是,最好不要创建自定义约束。我有一个简单的IComparer,它能很好地完成这个任务。它与EqualTo()一起工作。使用(),只要实际类型和预期类型相同。看起来,EqualsConstraint的AdjustArgumentIfNeeded方法在我的IComparer开始工作之前未能通过断言 我该怎么做才能允许任何形式的测试Assert.That(实际的,Is.EqualTo(预期的)
Assert将IConvertible
与DateTime
中的任意两个内容进行比较。这是,最好不要创建自定义约束。我有一个简单的IComparer
,它能很好地完成这个任务。它与EqualTo()一起工作。使用()
,只要实际类型和预期类型相同。看起来,EqualsConstraint
的AdjustArgumentIfNeeded
方法在我的IComparer
开始工作之前未能通过断言
我该怎么做才能允许任何形式的测试Assert.That(实际的,Is.EqualTo(预期的)。使用(DateTimeComparer.Instance))代码>如果实际和预期可以转换为同一日期时间,则通过,否则失败
这里有一个MCVE,它显示了两个测试,当我比较从不同格式字符串转换的日期时通过,但当比较转换的日期和实时日期时失败
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方法中找到:
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,通过IEnumerable
)。如果CanCompare返回false,它甚至不会进入自定义比较器查看参数是否相等,框架将运行默认的比较逻辑。我不认为CanCompare在与任何基本的使用(IComparer)
类型约束一起使用时会被覆盖。这是一个您必须在NUnit中提交才能完全解决的问题。我相信观察到的行为的原因可以在CanCompare方法中找到:
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,通过IEnumerable
)。如果CanCompare返回false,它甚至不会进入自定义比较器查看参数是否相等,框架将运行默认的比较逻辑。我不认为CanCompare在与任何基本的使用(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);
}
}
公共类DateTimeComparer:IComparer
{
公共静态只读DateTimeComparer实例=新建DateTimeComparer();
公共整数比较(IConvertible x,IConvertible y)
{
var dateTime1=Convert.ToDateTime(x);
var dateTime2=Convert.ToDateTime(y);
返回日期时间1.CompareTo(日期时间2);
}
}
进一步调查后,我发现正确的行为已经实现,只是在默认的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);
}
}
公共类DateTimeComparer:IComparer
{
公共静态只读DateTimeComparer实例=新建DateTimeComparer();
公共整数比较(IConvertible x,IConvertible y)
{
var dateTime1=Convert.ToDateTime(x);
var dateTime2=Convert.ToDateTime(y);
返回日期时间1.CompareTo(日期时间2);
}
}
目前我的解决方法是对所有实际值和预期值调用ToString()
。这显然是一个骇客行为,让我面临可能的文化问题(因为仍有一些人将“02/08/2016”解读为2月份的某个时间…),但它目前正在发挥作用。我目前的解决方法是调用ToString()
,查看我所有的实际值和预期值。这显然是有问题的,让我面临可能的文化问题(因为仍然有一些人在2月份的某个时候读到“02/08/2016”),但它现在起作用了。是的,我敢打赌这不是Charlie对这段代码的想法。也许应该是“如果其中一个是可数的,而另一个不是”。即使如此,如果提供了使用
的CanCompare
功能,也应该跳过它。很好!SOMBOID将其归档。:-)存档于。抱歉花了这么长时间,我完全忘了!我目前工作不足,所以我将尝试构建NUnit,编写一些测试等。但在我能够构建之前,我不会声明这个问题。很抱歉,我无法接受。你的回答仍然有用。但是另一种实现(使用通用适配器而不是普通适配器)对未来的寻求答案者更有帮助。是的,我敢打赌这不是Charlie对这段代码的想法。也许应该是“如果其中一个是可数的,而另一个不是”。即使如此,如果提供了使用
的CanCompare
功能,也应该跳过它。很好!SOMBOID将其归档。:-)存档于。抱歉花了这么长时间,我完全忘了!我目前工作不足,所以我将尝试构建NUnit,编写一些测试等。但在我能够构建之前,我不会声明这个问题。很抱歉,我无法接受。你的回答仍然有用。但是替代的实现(使用通用适配器而不是普通适配器)对未来的寻求答案者更有帮助。或者使用IComparer
帮助(当没有其他共同祖先时)。或者使用IComparer
帮助(当没有其他共同祖先时)。