Assert.AreNotEqual和Assert.AreNotSame有什么区别?

时间:2009-02-12 21:07:54

标签: c# .net unit-testing testing assert

在C#中,

之间有什么区别
Assert.AreNotEqual

Assert.AreNotSame

6 个答案:

答案 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);

AreNotEqualAreNotSame当然只是AreEqualAreSame的反转。

编辑:反驳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);

firstNumbersecondNumber都没有对象值,因为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()将触发失败的断言,但另一个不会。