MVC SelectListItem不实现等于?

时间:2012-02-03 00:48:01

标签: c# asp.net-mvc-3 unit-testing equality

忙于为控制器编写单元测试,该控制器生成一个视图模型,该视图模型包含一个选项列表,如IEnumerable< SelectListItem>。我尝试检查预期列表是否包含视图模型中的所有列表,反之亦然。令我惊讶的是,这总是错误的。所以我创建了以下测试:

[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 个答案:

答案 0 :(得分:2)

这是因为默认情况下,它正在测试相同的参考。在这种情况下,您有两个对象实例,因此它们不是“相等”。

如果要更改该行为,只需实现IEquatable<T>界面,即可重新定义Equals()将返回的内容。例如:

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

有关Object.Equals()的详细参考,请参阅this MSDN reference。参考类型的平等基于它们的参考。即如果他们没有引用相同的对象,则Equals()将返回false

答案 1 :(得分:2)

添加Shark的答案......至于如何处理它,除了在派生类上实现IEquatable<T>之外(如果你这样做,你真的应该覆盖非泛型Equals() - 如果你,你真的应该覆盖GetHashCode())......无论如何......除了这样做,你可以:

  1. 在测试项目中创建一个帮助器方法来进行值比较(可以使用适用于大多数简单类的Reflection编写一个通用的方法),或者
  2. 为您需要比较的每种类型创建一个帮助类,实现IEqualityComparer<T>
  3. 两者都不允许你使用Assert.AreEqual(),但总的来说,我不赞成为你的对象添加代码以便允许测试 - 更喜欢将它保存在测试项目中。另外,使用这些方法,您不需要“实施GetHashCode()等等。