在C#中,
之间有什么区别Assert.AreNotEqual
和
Assert.AreNotSame
答案 0 :(得分:81)
这里给出的几乎所有答案都是正确的,但它可能值得举个例子:
public static string GetSecondWord(string text)
{
// Yes, an appalling implementation...
return text.Split(' ')[1];
}
string expected = "world";
string actual = GetSecondWord("hello world");
// Good: the two strings should be *equal* as they have the same contents
Assert.AreEqual(expected, actual);
// Bad: the two string *references* won't be the same
Assert.AreSame(expected, actual);
AreNotEqual
和AreNotSame
当然只是AreEqual
和AreSame
的反转。
编辑:反驳currently accepted answer ......
如果您将Assert.AreSame
与值类型一起使用,则会将它们装箱。换句话说,它等同于:
int firstNumber = 1;
int secondNumber = 1;
object boxedFirstNumber = firstNumber;
object boxedSecondNumber = secondNumber;
// There are overloads for AreEqual for various value types
// (assuming NUnit here)
Assert.AreEqual(firstNumber, secondNumber);
// ... but not for AreSame, as it's not intended for use with value types
Assert.AreSame(boxedFirstNumber, boxedSecondNumber);
firstNumber
和secondNumber
都没有对象值,因为int
是值类型。 AreSame
调用失败的原因是因为在.NET中,装箱值每次都会创建一个新框。 (在Java中,有时候它没有 - 这在以前引起了我的兴趣。)
基本上,在比较值类型时,永远不会使用AreSame
。当您比较引用类型时,如果要检查相同的引用,请使用AreSame
;使用AreEqual
检查Equals
下的等效性。编辑:请注意是的情况,其中NUnit不直接使用Equals
;它内置了对集合的支持,集合中的元素被测试是否相等。
答案中的主张:
使用上面的示例更改 int到string,AreSame和AreEqual 将返回相同的值。
完全取决于变量的初始化方式。如果他们使用字符串文字,那么,实习将负责这一点。但是,如果您使用:
string firstString = 1.ToString();
string secondString = 1.ToString();
然后AreSame和AreEqual几乎肯定会不返回相同的值。
至于:
一般的经验法则是使用 AreEqual在值类型和AreSame上 参考类型。
我几乎从不想要检查参考标识。这对我来说很少有用。我想检查等价,这是AreEqual
检查的内容。 (我不是说AreSame
不应该存在 - 它是一种有用的方法,比AreEqual
更为罕见。)
答案 1 :(得分:25)
两件事可以是平等的,但不同的对象。 AreNotEqual通过相等性测试检查对象值,而AreNotSame检查它们不是完全相同的对象。
很明显,为什么我们要测试AreNotEqual(我们关心被测试的值);怎么样AreNotSame?当你传递了引用并且想要确保在你的改组完成后,两个引用仍然是同一个对象时,就会发现它在测试中的用处。
在现实世界中,我们使用大量缓存对象来减少到数据库的往返。在将对象传递到缓存系统之后,我们的单元测试确保在某些情况下我们返回相同的对象(缓存有效),在其他情况下我们返回新鲜对象(缓存)无效)。请注意,在这种情况下,AreNotEqual不一定足够。如果对象在数据库中有一个新的时间戳,但数据没有“足够差”而无法通过相等测试,则AreNotEqual不会注意到我们刷新了对象
答案 2 :(得分:19)
AreNotSame确实参考比较,而AreNotEqual进行相等比较。
答案 3 :(得分:8)
Assert.AreNotEqual断言两个值彼此不相等。
Assert.AreNotSame断言两个变量不指向同一个对象。
示例1:
int i = 1; int j = i; // The values are equal: Assert.AreEqual(i, j); // Two value types do *not* represent the same object: Assert.AreNotSame(i, j);
示例2:
string s = "A"; string t = s; // The values are equal: Assert.AreEqual(s, t); // Reference types *can* point to the same object: Assert.AreSame(s, t);
答案 4 :(得分:7)
AreNotSame使用引用相等(object.ReferenceEquals
) - 即它们是对象的实际实例; AreNotEqual使用概念上的相等(.Equals
) - 即它们被视为相等。
答案 5 :(得分:3)
不是AreNotEqual检查两个对象在Equals()方法上不相等的情况,而AreNotSame检查两个对象引用不相同的情况。因此,如果x和y是两个在Equals()方面相等但已经单独分配的对象,则AreNotEqual()将触发失败的断言,但另一个不会。