17

我有一个非常奇怪的行为,我无法解释。

我有以下课程:

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);
}

但是,当我运行单元测试时,将两个对象的类型与以下错误进行比较时失败:

Assert.AreEqual 失败。预期:<MyProject.NHibernate.Project>。实际:<MyProject.NHibernate.Project>。

为什么断言失败?


Assert.AreEqual不是仅对对象的属性进行断言吗?

根据文档:

Assert.AreEqual 方法(对象,对象)

验证两个指定对象是否相等。如果对象不相等,则断言失败。

Assert.AreSame 方法

验证指定的对象变量是否引用相同的对象。

4

4 回答 4

27

您需要重写 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 上覆盖等于的指南。

于 2013-03-17T16:21:17.197 回答
9

确保你的Project类覆盖了 equals 方法。目前您正在比较对象引用,并且由于您有 2 个不同的对象,ProjectAssert.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 。

于 2013-03-17T16:25:32.607 回答
1

您正在比较两个拥有相同数据的不同对象。您应该在 Project 类中重载 Equals 方法,并在那里通过 id 实现比较。

于 2013-03-17T16:16:40.043 回答
1

一个简单的替代方案是:

Assert.IsTrue(string1 == string2, "Error");
于 2016-11-30T07:31:30.310 回答