以下不是XUnit断言为真(StartDate和EndDate是DatePeriod的唯一两个公共属性):
var actual = new List<DatePeriod>()
{
new DatePeriod() { StartDate = new DateTime(2017, 1, 20), EndDate = new DateTime(2018, 1, 19)},
new DatePeriod() { StartDate = new DateTime(2018, 1, 20), EndDate = new DateTime(2018, 3, 31)}
};
var expected = new List<DatePeriod>()
{
new DatePeriod() { StartDate = new DateTime(2017, 1, 20), EndDate = new DateTime(2018, 1, 19)},
new DatePeriod() { StartDate = new DateTime(2018, 1, 20), EndDate = new DateTime(2018, 3, 31)}
};
Assert.Equal(actual, expected);
根据我在最新版本的XUnit中所预期的一些研究,这些最终被认为是相同的,因为只要订单与它是相同的,就会使用Assert。
答案 0 :(得分:4)
您只需要覆盖Equals
和GetHashCode
,如下所示:
public class DatePeriod
{
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true;
if (obj.GetType() != this.GetType()) return false;
DatePeriod other = (DatePeriod)obj;
return StartDate.Equals(other.StartDate) && EndDate.Equals(other.EndDate);
}
public override int GetHashCode()
{
return new {StartDate, EndDate}.GetHashCode();
}
public DateTime StartDate { get; set; }
public DateTime EndDate { get; set; }
}
xUnit可识别集合,您可以调用Assert.Equal
,而其他测试框架需要CollectionAssert.AreEqual
等特殊方法。
在所有情况下,框架都会为列表中的每个项调用Equals
,从而传递另一个列表中的相应项。如果您有字符串或整数列表,则默认情况下会正确实现Equals
。对于DatePeriod
之类的自定义对象,Equals
方法的默认实现基于引用相等性,即两个对象相等,它们实际上是同一个对象。要获得基于值的相等性,您必须覆盖Equals
方法(以及建议的GetHashCode
方法)。
答案 1 :(得分:2)
List<T>
等式不是元素到元素的检查。
使用LINQ的SequenceEqual方法检查您的平等性。
var equal = actual.SequenceEqual(expected);
在您的对象上实施IEquatable
:
public class DatePeriod : IEquatable<DatePeriod>
{
public DateTime StartDate { get; set; }
public DateTime EndDate { get; set; }
public bool Equals(Period other)
{
return StartDate == other.StartDate && EndDate == other.EndDate;
}
}
为安全起见,请检查是否有空。有关更完整的实施,请参阅Yacoub的答案。