C#测试-自定义类型的比较列表
我正在尝试编写测试检查JSON转换器是否正确地将输入反序列化到我的自定义列表C#测试-自定义类型的比较列表,c#,unit-testing,assert,fluent-assertions,C#,Unit Testing,Assert,Fluent Assertions,我正在尝试编写测试检查JSON转换器是否正确地将输入反序列化到我的自定义列表 [TestMethod] public void JSONInput_Changed() { List<PointOnChart> _expectedPointsOnChart; _expectedPointsOnChart = new List<PointOnChart>(); _expectedPointsOnChart
[TestMethod]
public void JSONInput_Changed()
{
List<PointOnChart> _expectedPointsOnChart;
_expectedPointsOnChart = new List<PointOnChart>();
_expectedPointsOnChart.Add(new PointOnChart { Timestamp = "2020-02-14T09:00:00.000Z", Value1 = 10, Value2 = 20, Value3 = 30 });
_expectedPointsOnChart.Add(new PointOnChart { Timestamp = "2020-02-14T09:01:00.000Z", Value1 = 11, Value2 = 21, Value3 = 31 });
_expectedPointsOnChart.Add(new PointOnChart { Timestamp = "2020-02-14T09:02:00.000Z", Value1 = 12, Value2 = 22, Value3 = 32 });
_expectedPointsOnChart.Add(new PointOnChart { Timestamp = "2020-02-14T09:03:00.000Z", Value1 = 13, Value2 = 23, Value3 = 33 });
MultipleBarChart multipleBarChartTest = new MultipleBarChart();
multipleBarChartTest.MeInitialize(DateTimeIntervalType.Minutes);
string JSONstring = System.IO.File.ReadAllText(@"C:\Users\slawomirk\source\repos\VIXCharts\iFixMultipleBarChartTests\TestJson.txt");
multipleBarChartTest.JSONInput = JSONstring;
List<PointOnChart> resultPointsOnChart = multipleBarChartTest.PointsOnChart;
//bool areEqual = _expectedPointsOnChart.SequenceEqual(resultPointsOnChart);
IEnumerable<PointOnChart> resultList;
resultList = _expectedPointsOnChart.Except(resultPointsOnChart);
if (resultList.Any())
{
Assert.Fail();
}
}
这是我正在读取的反序列化文件:
[{“时间戳”:“2020-02-14T09:00:00.000Z”,“Value1”:10,“Value2”:20,“Value3”:30},
{“时间戳”:“2020-02-14T09:01:00.000Z”,“Value1”:11,“Value2”:21,“Value3”:31},
{“时间戳”:“2020-02-14T09:02:00.000Z”,“Value1”:12,“Value2”:22,“Value3”:32},
{“时间戳”:“2020-02-14T09:03:00.000Z”,“Value1”:13,“Value2”:23,“Value3”:33}]
我尝试了许多方法来比较两个列表,但都失败了,例如:
-流畅的断言
-收藏家
当我在调试中检查这两个列表时,它们是相同的。
我知道这可能很琐碎,但我可以在网上找到任何解决方案,提前谢谢。您应该为
PointOnChart
类实现Equals
方法,类似这样:
public override bool Equals(object other)
{
if (object.ReferenceEquals(other, this)) return true;
var obj = other as PointOnChart;
if (obj == null) return false;
return this.Timestamp == obj.Timestamp && this.Value1 == obj.Value1 && this.Value2 == obj.Value2 && this.Value3 == obj.Value3;
}
这样,
SequenceEquals
扩展方法将正常运行。而不是使用Equals
覆盖来污染生产代码,考虑使用www.fluentassertions.com并将该语句编写为:
resultPointsOnChart.Should().BeEquivalentTo(expectedPointsOnChart)
除了其他答案之外,我建议实现IEquatable
以及像这样重写GetHashCode()
和等于(对象)
公共类PointOnChart:IEquatable{
公共字符串时间戳{get;set;}
公共双值1{get;set;}
公共双值2{get;set;}
公共双值3{get;set;}
公共重写Int32 GetHashCode()=>Timestamp.GetHashCode()^Value1.GetHashCode()^Value2.GetHashCode()^Value3.GetHashCode();
公共覆盖布尔等于(对象obj)=>Equals(对象obj作为PointOnChart);
公共布尔等于(PointOnChart-other)=>other!=null&&other.Timestamp==Timestamp&&other.Value1.Equals(Value1)和&other.Value2.Equals(Value2)和&other.Value3.Equals(Value3);
}
这将为您提供所需的所有比较。
如果以后需要,还可以更轻松地实现
IEqualityComparer
或IEqualityComparer
。您是否尝试过使用自定义IEqualityComparer的?由于您尚未在PointOnChart
本身中定义一种确定相等性的方法,测试框架将无法判断两者是否相同。PointOnChart
看起来如何?您忘记了GetHashCode()
SequenceEquals将只使用Equals方法,尽管为了完整性,是的,我们还应该实现GetHashCode。您应该在自己的IEqualityComparer
类中真正实现这些方法。否则,您可能会遇到棘手的问题,特别是如果您开始从这个类派生,而其他人开始调用您的Equals()
和GetHashCode()
方法(如Dictionary
或Distinct()
,Join()
等LINQ方法)。不同意,我认为学生应该知道如何比较自己,这在很多情况下都很有用。完全不同意。我认为类应该知道如何比较自己,它在很多地方都很有用。这很大程度上取决于类是否应该具有值语义。如果没有(因为它是域中的一个实体),那么添加Equals
会把事情搞砸。例如,当您持久化的对象覆盖等于时,NHibernate会突然表现出不同的行为。这与你在单元测试中想要的东西是正交的,“搞砸了”?你知道你在说什么吗?这实际上是NHibernate所必需的!看吧,对我来说25年了,很少有书是这样写的。。。但正如我说的,没关系。
public override bool Equals(object other)
{
if (object.ReferenceEquals(other, this)) return true;
var obj = other as PointOnChart;
if (obj == null) return false;
return this.Timestamp == obj.Timestamp && this.Value1 == obj.Value1 && this.Value2 == obj.Value2 && this.Value3 == obj.Value3;
}