断言.AreEqual失败了,而它不应该失败
本文关键字:失败 不应该 AreEqual 断言 | 更新日期: 2023-09-27 18:04:26
我有一个非常奇怪的行为,我无法解释。
我有以下类:
public class Project
{
public virtual int Id { get; set; }
public virtual string Name { get; set; }
}
和一个返回Project
对象的方法:
public Project GetByName(string Name)
{
using (ISession session = NHibernateHelper.OpenSession())
{
Project project = session.CreateCriteria(typeof(Project))
.Add(Restrictions.Eq("Name", Name))
.UniqueResult<Project>();
return project;
}
}
我添加了一个单元测试来测试GetByName
方法:
[TestMethod]
public void TestGetByName()
{
IProjectsRepository projectRepository = new ProjectsRepository();
var expected = new Project { Id = 1000, Name = "Project1" };
var actual = projectRepository.GetByName(expected.Name);
Assert.AreEqual<Project>(expected, actual);
}
但是当我运行单元测试时,它在比较两个对象的类型时失败,并出现以下错误:
断言。AreEqual失败了。预期:& lt; MyProject.NHibernate.Project>。实际:& lt; MyProject.NHibernate.Project>.
为什么断言失败?
不是断言。是否equal只对对象的属性进行断言?
根据文档:
断言。AreEqual方法(Object, Object)
验证两个指定的对象是否相等。如果断言失败对象不相等
断言。AreSame Method
验证指定的对象变量是否引用同一对象。
您需要重写equals方法来测试是否相等。默认情况下,它将使用引用比较,并且由于您期望的对象和实际对象位于内存中的不同位置,因此它将失败。下面是你应该尝试的:
public class Project
{
public virtual int Id { get; set; }
public virtual string Name { get; set; }
public override bool Equals(Object obj)
{
if (obj is Project)
{
var that = obj as Project;
return this.Id == that.Id && this.Name == that.Name;
}
return false;
}
}
你也可以查看在MSDN上重写等号的指南
确保你的Project
类覆盖了equals方法。当前您正在比较对象引用,并且由于您有Project
的两个不同对象,您的Assert.AreEqual()
将失败。
public class Project
{
public virtual int Id { get; set; }
public virtual string Name { get; set; }
public override bool Equals(object o)
{
var result = false;
var project = o as Project;
if (project != null)
{
result = Id == project.Id;
result &= Name.Equals(project.Name);
return result;
}
return false;
}
}
equals方法就绪后,您可以使用Assert.AreEqual
[TestMethod]
public void TestGetByName()
{
IProjectsRepository projectRepository = new ProjectsRepository();
var expected = new Project { Id = 1000, Name = "Project1" };
var actual = projectRepository.GetByName(expected.Name);
Assert.AreEqual<Project>(expected, actual);
}
PS:如果你要覆盖Equals,建议也覆盖Hashcode。
public override int GetHashCode()
{
var hashcode = Id.GetHashCode();
hashCode ^= Name.GetHashCode();
return hashCode;
}
AreSame vs AreEqual
Assert.AreSame
仍然会失败,即使您覆盖了Equals
方法。该方法实际上检查引用是否指向同一个实例。而在你的情况下,他们不会。
Assert.AreEqual
将简单地检查对象是否相等,这将通过调用expected.Equals(actual)
来完成。一旦您实现了override bool Equals()
方法,结果将为true。
您正在比较保存相同数据的两个不同对象。您应该在Project类中重载Equals方法,并在那里实现按id进行比较。
一个简单的替代方法是:
Assert.IsTrue(string1 == string2, "Error");
如果你有一个简单的类,并且你想方便地比较它,你可以使用元组:
using System.Linq
public class Project
{
public virtual int Id { get; set; }
public virtual string Name { get; set; }
}
[TestMethod]
public void TestProject()
{
var collection1 = Project[] { new() { Id = 1, Name = "Project1" } };
var collection2 = Project[] { new() { Id = 2, Name = "Project2" } };
CollectionAssert.AreEqual(
collection1.Select(p => (p.Id, p.Name)).ToArray(),
collection2.Select(p => (p.Id, p.Name)).ToArray());
}
公认的答案是正确的,但我认为我应该添加一个非常简单的实现,适用于任何类:
public override bool Equals(object obj)
{
return GetType().GetProperties().All(property => property.GetValue(this) == property.GetValue(obj));
}
它基本上遍历每个属性并相互检查值