C# 比较两个列表<;T>;使用XUnit断言函数
以下内容不适用于XUnit(StartDate和EndDate是DatePeriod仅有的两个公共属性):C# 比较两个列表<;T>;使用XUnit断言函数,c#,assert,xunit,xunit.net,xunit2,C#,Assert,Xunit,Xunit.net,Xunit2,以下内容不适用于XUnit(StartDate和EndDate是DatePeriod仅有的两个公共属性): var实际值=新列表() { 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预期值=新列
var实际值=新列表()
{
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预期值=新列表()
{
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)}
};
断言。相等(实际、预期);
根据一些研究,我希望在最新版本的XUnit中,只要顺序与实际相同,就可以认为它们是相等的。List
元素间不检查相等性
使用LINQ的方法检查您的相等性
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;
}
}
public类DatePeriod:IEquatable
{
公共日期时间起始日期{get;set;}
公共日期时间结束日期{get;set;}
公共bool等于(其他期间)
{
返回StartDate==other.StartDate&&EndDate==other.EndDate;
}
}
为了安全起见,请检查是否存在空值。有关更完整的实现,请参见Yacoub的答案。您只需覆盖
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
方法)。是期间定义的Equals
和GetHashCode
方法吗?不,这是我需要做的吗?@YacoubMassad请查看我对您答案的评论,我不得不稍微更新我的帖子,因为没有句点对象,所有的东西都使用DatePeriod。嘿,这似乎正是我需要的,但是你能看看我最近对帖子的更新吗。我很抱歉,因为没有句号这样的对象。一切都使用DatePeriod。@BlakeRivell您最初有一个列表,其中包含一系列句点,这使Yacoub相信句点子类DatePeriod。@Theanatherma是正确的,这就是为什么我试图让他知道我在评论中的错误,并问他是否可以更新他的答案。否,有时我使用它是因为我有一个自定义的比较逻辑,它不是对象本身固有的。例如,我只想通过ID
比较一些情况,而不想比较其他属性。例如,当您创建一个字典时,您可以传递这样的自定义比较器。如果有一种“标准”方法来比较对象,那么您应该将这样的比较逻辑放在对象本身上。如果比较逻辑是自定义的,则将其放在自定义对象中(实现IEqualityComparer
)。
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; }
}