Вопрос

В 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 конечно.

Редактировать:Опровержение к принятый в настоящее время ответ...

Если вы используете 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.)

Другие советы

Две вещи могут быть равными, но разными объектами.AreNotEqual проверяет объекты ценности с помощью теста на равенство, в то время как AreNotSame проверяет, что они не являются одним и тем же точным объектом.

Очевидно, почему мы хотели бы проверить, что вещи не равны (мы заботимся о тестируемых значениях);а как насчет AreNotSame?Полезность этого при тестировании обнаруживается, когда вы передаете ссылки по кругу и хотите убедиться, что после завершения перетасовки две ссылки по-прежнему являются одним и тем же объектом.

В реальном случае мы используем множество объектов кэширования, чтобы уменьшить циклический доступ к базе данных.После того, как объект был передан в систему кэширования, наши модульные тесты гарантируют, что в некоторых случаях мы получаем обратно тот же объект (кэш был действительным), а в других случаях мы получаем обратно свежий объект (кэш был признан недействительным).Обратите внимание, что AreNotEqual в этом случае было бы необязательно достаточным.Если у объекта была новая временная метка в базе данных, все же данные был недостаточно "другим", чтобы провалить тест на равенство, AreNotEqual не заметил бы, что мы обновили объект.

Это одно и то же выполняет ссылочное сравнение, тогда как Не равны выполняет сравнение на равенство.

Утверждать.AreNotEqual утверждает, что два значения не равны друг другу.

Утверждать.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);

AreNotSame использует ссылочное равенство (object.ReferenceEquals) - т. е.являются ли они одним и тем же фактическим экземпляром объекта;AreNotEqual использует концептуальное равенство (.Equals) - т. е.являются ли они рассмотренный равный.

Разве это не так, что AreNotEqual проверяет случай, когда два объекта не равны с точки зрения метода Equals(), тогда как AreNotSame проверяет случай, когда две ссылки на объекты не совпадают.Таким образом, если x и y - это два объекта, которые равны с точки зрения Equals(), но были выделены отдельно, AreNotEqual() вызовет ошибочное утверждение, а другое - нет.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top