web-dev-qa-db-ja.com

Assert.AreEqualは失敗するはずですが失敗します

私は説明できない本当に奇妙な行動をしています。

私は次のクラスを持っています:

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

しかし、単体テストを実行すると、2つのオブジェクトのタイプを比較すると失敗し、次のエラーが発生します。

Assert.AreEqualが失敗しました。期待:<MyProject.NHibernate.Project>。実際:<MyProject.NHibernate.Project>。

アサーションが失敗するのはなぜですか?


Assert.AreEqual オブジェクトのプロパティのみをアサートしていませんか?

ドキュメントによると:

Assert.AreEqualメソッド(オブジェクト、オブジェクト)

指定された2つのオブジェクトが等しいことを確認します。オブジェクトが等しくない場合、アサーションは失敗します。

Assert.AreSameメソッド

指定されたオブジェクト変数が同じオブジェクトを参照していることを確認します。

15
chaliasos

等しいかどうかをテストするには、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で equalsをオーバーライドするためのガイドライン を確認することもできます。

25
Corey Sunwold

Projectクラスがequalsメソッドをオーバーライドしていることを確認してください。現在、オブジェクト参照を比較していますが、Projectの2つの異なるオブジェクトがあるため、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をオーバーライドする場合は、 推奨 ハッシュコードもオーバーライドします。

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

AreSameとAreEqual

Equalsメソッドをオーバーライドしても、_Assert.AreSame_は失敗します。そのメソッドは、参照が同じインスタンスを指しているかどうかを実際にチェックします。あなたの場合、彼らはそうしません。

_Assert.AreEqual_は、オブジェクトが等しいかどうかを単にチェックします。これは、expected.Equals(actual)を呼び出すことによって行われます。 override bool Equals()メソッドを実装すると、trueになります。

8
bas

同じデータを保持する2つの異なるオブジェクトを比較しています。 ProjectクラスのEqualsメソッドをオーバーロードし、そこでidによる比較を実装する必要があります。

1
alex

簡単な代替手段は次のとおりです。

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