C# NUnit 比较两个列表
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19861619/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
NUnit comparing two lists
提问by SOfanatic
OK so I'm fairly new to unit testing and everything is going well until now. I'm simplifying my problem here, but basically I have the following:
好的,所以我对单元测试还很陌生,直到现在一切都进展顺利。我在这里简化了我的问题,但基本上我有以下几点:
[Test]
public void ListTest()
{
var expected = new List<MyClass>();
expected.Add(new MyOtherClass());
var actual = new List<MyClass>();
actual.Add(new MyOtherClass());
Assert.AreEqual(expected,actual);
//CollectionAssert.AreEqual(expected,actual);
}
But the test is failing, shouldn't the test pass? what am I missing?
但是测试失败,测试不应该通过吗?我错过了什么?
采纳答案by Sriram Sakthivel
I convert my comment to answer on request.
我将我的评论转换为应要求回答。
Well, this fails because AreEqual
uses reference comparison. In order to make it work you need value comparison(your own custom comparison).
好吧,这失败了,因为AreEqual
使用了引用比较。为了使其工作,您需要进行价值比较(您自己的自定义比较)。
You can pretty much do that by implementing IEquatableinterface. and keep in mind when you're implementing this interface you mustoverride Object.Equals
and Object.GetHashCode
as well to get consistent results.
您几乎可以通过实现IEquatable接口来做到这一点。并记住,当您实现此接口时,您必须覆盖Object.Equals
并Object.GetHashCode
获得一致的结果。
.Net framework supports doing this without implementing IEquatable
you need IEqualityComparerthat should do the trick, but nunit
should have a method which takes this as a overload. Am not certain about "nunit" though.
.Net 框架支持在不实现的情况下执行此操作,IEquatable
您需要IEqualityComparer应该可以解决问题,但nunit
应该有一个将其作为重载的方法。虽然我不确定“nunit”。
回答by Noctis
From Nunit documentation:
从 Nunit文档:
Starting with version 2.2, special provision is also made for comparing single-dimensioned arrays. Two arrays will be treated as equal by Assert.AreEqual if they are the same length and each of the corresponding elements is equal. Note: Multi-dimensioned arrays, nested arrays (arrays of arrays) and other collection types such as ArrayList are not currently supported.
从 2.2 版本开始,还为比较单维数组做出了特殊规定。如果两个数组的长度相同并且每个相应的元素相等,则 Assert.AreEqual 将它们视为相等。注意:当前不支持多维数组、嵌套数组(数组的数组)和其他集合类型,例如 ArrayList。
You have a list of objects ... so it's not the same as comparing 2 ints. What you should do is probably compare all the objects inside the list ... (Try converting your list to an array ... might actually work :) )
你有一个对象列表......所以它与比较 2 个整数不同。您应该做的可能是比较列表中的所有对象...(尝试将您的列表转换为数组...实际上可能有效:))
As I said (and most others as well), you'll probably need to override Equals. Here's MSDNpage about how to do it (Covers Equals, == operator, and GetHashCode).
正如我所说(以及大多数其他人),您可能需要覆盖 Equals。这是有关如何执行此操作的MSDN页面(涵盖 Equals、== 运算符和 GetHashCode)。
Similar with more info :
[compare-equality-between-two-objects-in-nunit]
(Compare equality between two objects in NUnit)
与更多信息类似:[compare-equality-between-two-objects-in-nunit]
(比较 NUnit 中两个对象之间的相等性)
回答by Klark
Try to be a bit more specific about what you are trying to achieve. Explicitly telling that you want to compare entire sequence will solve the problem. I personally wouldn't rely on NUnit fancy features for determining what you meant by says AreEqual. E.g.
尝试更具体地说明您要实现的目标。明确告诉您要比较整个序列将解决问题。我个人不会依赖 NUnit 奇特的功能来确定你所说的 AreEqual 的意思。例如
Assert.IsTrue(actual.SequenceEqual(expected));
回答by Jeff B
A very simple way to get this test to work is to only create the MyOtherClass
instance once. That way, when comparing the item in the two lists they will be "equal" (because they reference the same object). If you do this, CollectionAssert
will work just fine.
让这个测试工作的一个非常简单的方法是只创建MyOtherClass
一次实例。这样,当比较两个列表中的项目时,它们将“相等”(因为它们引用相同的对象)。如果你这样做,CollectionAssert
将工作得很好。
[Test]
public void ListTest()
{
var thing = new MyOtherClass();
var expected = new List<MyClass>();
expected.Add(thing);
var actual = new List<MyClass>();
actual.Add(thing);
CollectionAssert.AreEqual(expected,actual);
}
If you don't this though, you'll need to implement IEquatable<MyOtherClass>
in MyOtherClass
or override Equals
to define what makes two instances of that class the "same".
如果不这样做,则需要实现IEquatable<MyOtherClass>
inMyOtherClass
或 overrideEquals
以定义使该类的两个实例“相同”的原因。
回答by matth
If you're comparing two lists, you should use test using collection constraints.
如果要比较两个列表,则应使用集合约束进行测试。
Assert.That(actual, Is.EquivalentTo(expected));
Also, in your classes, you will need to override the Equals method, otherwise like gleng stated, the items in the list are still going to be compared based on reference.
此外,在您的类中,您将需要覆盖 Equals 方法,否则就像 gleng 所述,列表中的项目仍将根据参考进行比较。
Simple override example:
简单的覆盖示例:
public class Example
{
public int ID { get; set; }
public override bool Equals(object obj)
{
return this.ID == (obj as Example).ID;
}
}
回答by Pavel Yermalovich
If you can't modify a class then this example can be helpful:
如果您无法修改类,那么此示例可能会有所帮助:
[Test]
public void Arrays_Should_Be_Equal()
{
MyClass[] array1 = GetTestArrayOfSize(10);
MyClass[] array2 = GetTestArrayOfSize(10);
// DOESN'T PASS
// Assert.That(array1, Is.EquivalentTo(array2));
Func<MyClass, object> selector = i => new { i.Property1, i.Property2 };
Assert.That(array1.Select(selector), Is.EquivalentTo(array2.Select(selector)));
}
private MyClass[] GetTestArrayOfSize(int count)
{
return Enumerable.Range(1, count)
.Select(i => new MyClass { Property1 = "Property1" + i, Property2 = "Property2" + i }).ToArray();
}