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

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

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

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


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

ドキュメントによると:

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

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

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でequalsをオーバーライドするためのガイドラインを確認することもできます。

于 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をオーバーライドする場合は、ハッシュコードもオーバーライドすることをお勧めします。

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

AreSameとAreEqual

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

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

于 2013-03-17T16:25:32.607 に答える
1

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

于 2013-03-17T16:16:40.043 に答える
1

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

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