C# Assert.AreEqual 失败,而它不应该

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15463023/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 16:55:17  来源:igfitidea点击:

Assert.AreEqual fails while it shouldn't

c#visual-studio-2012mstestassert

提问by chaliasos

I have a really weird behavior which I cannot explain.

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

I have the following class:

我有以下课程:

public class Project
{
    public virtual int Id { get; set; }

    public virtual string Name { get; set; }
}

And a method which returns a Projectobject:

以及一个返回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;
    }
}

I have added a Unit Test to test the GetByNamemethod:

我添加了一个单元测试来测试该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);
}

But when I run the unit test it fails when comparing the type of the two objects with the following error:

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

Assert.AreEqual failed. Expected:<MyProject.NHibernate.Project>. Actual:<MyProject.NHibernate.Project>.

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

Why is the assertion failing?

为什么断言失败?



Isn't Assert.AreEqualasserting only on the properties of the objects?

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

According to the documentation:

根据文档:

Assert.AreEqual Method (Object, Object)

Verifies that two specified objects are equal. The assertion fails if the objects are not equal.

Assert.AreSame Method

Verifies that specified object variables refer to the same object.

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

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

Assert.AreSame 方法

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

采纳答案by Corey Sunwold

You need to override the equals method to test for equality. By default it will use reference comparison, and since your expected and actual objects are in different locations in memory it will fail. Here is what you should try:

您需要覆盖 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; 
    }
}

You can also check out the guidelines for overriding equalson MSDN.

您还可以在 MSDN 上查看覆盖 equals指南

回答by alex

You are comparing two different objects that hold the same data. You should overload Equals method in your Project class, and implement comparison by id there.

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

回答by bas

Make sure that your Projectclass overrides the equals method. Currently you are comparing object references, and since you have 2 different objects of Projectyour Assert.AreEqual()will fail.

确保您的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;
    }
}

With the equals method in place, you can use the Assert.AreEqual

使用 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: If you are overriding Equals it's advisedto also override the Hashcode.

PS:如果您要覆盖 Equals,建议也覆盖 Hashcode。

    public override int GetHashCode()
    {
        var hashcode = Id.GetHashCode();
        hashCode ^= Name.GetHashCode();
        return hashCode;
    }

AreSame vs AreEqual

AreSame 与 AreEqual

Assert.AreSamewill still fail, even when you override the Equalsmethod. That method actually checks if the references are pointing to the same instance. Which in your case, they will not.

Assert.AreSame即使您覆盖该Equals方法,仍然会失败。该方法实际上检查引用是否指向同一个实例。在你的情况下,他们不会。

Assert.AreEqualwill simply check if the objects are equal, which will be done by calling expected.Equals(actual). That will result in true once you implemented the override bool Equals()method.

Assert.AreEqual将简单地检查对象是否相等,这将通过调用expected.Equals(actual). 一旦您实现了该override bool Equals()方法,这将导致 true 。

回答by Sascha P

An easy alternative would be this:

一个简单的选择是这样的:

Assert.IsTrue(string1 == string2, "Error");