Assert.AreNotEqual和Assert.AreNotSame有什么区别?
在C#中,有什么区别
Assert.AreNotEqual
和
Assert.AreNotSame
这里给出的答案几乎都是正确的,但是可能值得举一个例子:
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
的反转。
编辑:反驳目前接受的答案 …
如果您使用值typesAssert.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
是一个值types。 AreSame
调用失败的原因是因为在.NET中,每次装箱时都会创build一个新的框。 (在Java中,它有时不会 – 这让我感觉到了。)
比较值types时,基本上不应该使用AreSame
。 在比较引用types时,如果要检查相同的引用,请使用AreSame
; 使用AreEqual
在Equals
下检查等价性。 编辑:请注意,有NUnit不直接使用Equals
; 它内置了对集合的支持,集合中的元素被testing为相等。
答案中的主张是:
使用上面的示例将int更改为string,AreSame和AreEqual将返回相同的值。
完全取决于variables是如何初始化的。 如果他们使用string文字,然而,实习会照顾这一点。 但是,如果您使用:
string firstString = 1.ToString(); string secondString = 1.ToString();
那么AreSame和AreEqual几乎肯定不会返回相同的值。
至于:
一般的经验法则是在值types上使用AreEqual,在引用types上使用AreSame。
我几乎从不想检查参考身份。 这对我来说很less有用。 我想检查AreEqual
检查的等价性 。 (我并不是说AreSame
不应该在那里 – 这是一个有用的方法,仅仅比AreEqual
。
两件事情可以是平等的,但不同的对象。 AreNotEqual通过相等性testing检查对象值 ,而AreNotSame检查它们不是相同的确切对象。
这显然是为什么我们要testing的东西AreNotEqual(我们关心的价值被testing); 那么AreNotSame呢? 这个在testing中的用处是在你传递了引用的时候find的,并且要确保在你的混洗完成后两个引用仍然是同一个对象。
在现实世界的情况下,我们使用了大量的caching对象来缓解数据库的往返行程。 在一个对象被移交给caching系统后,我们的unit testing确保在某些情况下我们得到相同的对象(caching有效),而在其他情况下,我们得到一个新的对象(caching失效)。 请注意,在这种情况下AreNotEqual不足以满足要求。 如果对象在数据库中有一个新的时间戳,但是数据没有足够的差异来通过相等性testing,AreNotEqual不会注意到我们刷新了对象 。
AreNotSame做参考比较,而AreNotEqual做比较。
Assert.AreNotEqual断言两个值不相等。
Assert.AreNotSame断言两个variables不指向同一个对象。
例1:
int i = 1; int j = i; //值相等: Assert.AreEqual(i,j); //两个值types不*代表同一个对象: Assert.AreNotSame(i,j);
例2:
strings =“A”; stringt = s; //值相等: Assert.AreEqual(s,t); //引用types*可以*指向相同的对象: Assert.AreSame(s,t);
AreNotSame使用引用相等(object.ReferenceEquals) – 即它们是一个对象的实际实例; AreNotEqual使用概念上的相等( .Equals
) – 即他们认为是平等的。
是不是这样,AreNotEqual检查两个对象不等于Equals()方法的情况,而AreNotSame检查两个对象的引用不相同的情况。 因此,如果x和y是Equals()方面相等的两个对象,但它们已经分开分配,AreNotEqual()会触发失败的断言,而另一个则不会。