MVC SelectListItem не реализует равные? - PullRequest
4 голосов
/ 03 февраля 2012

Занятое написание модульного теста для контроллера, который создает модель представления, которая включает в себя список опций как IEnumerable . Я попытался проверить, что ожидаемый список содержит все из них в модели представления и наоборот. К моему удивлению, это всегда ложно. Поэтому я создал следующий тест:

[TestMethod]
public void CanEqual()
{
  var x = new SelectListItem {Selected = false, Text = "A", Value = "A"};
  var y = new SelectListItem { Selected = false, Text = "A", Value = "A" };
  Assert.AreEqual(x, y); 
}

Утверждение всегда не выполняется, но оба равны. Действительно ли SelectListItem не реализует Equals или я просто что-то здесь упускаю?

Ответы [ 2 ]

2 голосов
/ 03 февраля 2012

Добавление к ответу Shark ... Что касается того, что с этим делать, кроме реализации IEquatable<T> в производном классе (и если вы это сделаете, вам действительно следует переопределить неуниверсальный Equals() - и если вы делаете , что , вы действительно должны переопределить GetHashCode()) ... В любом случае ... кроме этого, вы могли бы:

  1. Создайте вспомогательный метод в своем тестовом проекте для сравнения значений (можно написать метод общего назначения, используя Reflection, который будет работать для большинства простых классов), или
  2. Создайте вспомогательный класс, реализующий IEqualityComparer<T> для каждого из типов, которые необходимо сравнить.

Ни один из них не позволит вам использовать Assert.AreEqual(), но в целом я не одобряю добавление кода к вашим объектам только для того, чтобы разрешить тестирование - предпочитаю сохранять его в тестовом проекте. Кроме того, с этими подходами вам не нужно будет «внедрять» GetHashCode() и т. Д.

2 голосов
/ 03 февраля 2012

Это потому, что по умолчанию это тестирование по той же ссылке. В этом случае у вас есть два экземпляра объекта, поэтому они не «равны».

Если вы хотите изменить это поведение, вам просто нужно реализовать интерфейс IEquatable<T>, и вы можете переопределить то, что вернет Equals(). Например:

public bool Equals(YourClass other)
{
    return (this.Value == other.Value);
}

Хорошую справку по Object.Equals() см. по этой ссылке MSDN . Равенство для ссылочных типов основано на их ссылке. То есть если они не ссылаются на один и тот же объект, то Equals() вернет false.

...