4

MBUnit の 2 つのオブジェクトを比較して、それらが異なるインスタンスであっても、オブジェクトが同じように「見える」場合にテストに合格する方法があるかどうかを知りたいですか?

例えば:

[TestFixture]
class ComparisonTestFixture
{

    class foo
       {
           public string bar;
       }

    [Test]
    public void ComparisonTest()
    {

        foo foo1 = new foo()
           {
               bar = "baz"
           };

        foo foo2 = new foo()
            {
                bar = "baz"
            };


        //This assertion should be successful, but it isn't
        //*** Failures ***
        //Expected values to be equal.
        //Expected Value & Actual Value : {foo: bar = "zzz...."}
        //Remark : Both values look the same when formatted but they are distinct instances.
        Assert.AreEqual(foo1,foo2);
    }
}

Assert.AreEqual() はこれに対して機能しません (テストは失敗します。上記のソース コードを参照してください)。「フォーマットすると両方の値が同じように見えますが、それらは異なるインスタンスです」と述べているため、独自のコードでオブジェクトを XML にシリアル化せずに、MbUnit に組み込む方法が必要であると考えています。

これには独自の Assert 拡張メソッドを作成する必要がありますか?

4

4 に答える 4

7

Yann は、各プロパティの一連のラムダを指定して、プロパティ値を 1 つずつ比較する StructuralEqualityComparer も実装しました。一見の価値あり。

詳細はこちら: http://www.gallio.org/api/html/T_MbUnit_Framework_StructuralEqualityComparer_1.htm

于 2009-08-26T08:12:18.710 に答える
4

as パラメータを取るオーバーロードとAssert.AreEqual()IEqualityComparer<T>EqualityComparison<T>

それ以外の場合は使用できますAssert.AreEqual(Assert.XmlSerialize(a), Assert.XmlSerialize(b))

于 2009-08-25T13:16:26.123 に答える
1

私が通常行うことは、ToString() オーバーライドを実装することだけです。これは、とにかく実行するベスト プラクティスと見なされます。

だからあなたの場合:

public override string ToString()
{
    return string.Format("Class foo, bar={0}",bar);
}

その後AreEqual(foo1,foo2)、デフォルトの ToString 実装を呼び出すだけなので、実際には正しい結果が報告されます

于 2009-08-27T17:26:52.480 に答える
1

クラスのメソッドをオーバーライドして、必要Equalsな比較を実行することをお勧めします。これにより、参照の等価性の代わりに値の等価性を定義できます。1 つの注意点は、等しい 2 つのオブジェクトが同じハッシュ コードを返すようにオーバーライドするGetHashCode場合は、オーバーライドする必要があることです。Equalsこれは非常に簡単な例です。

public class Foo {

  public String Bar {
    get;
    set;
  }

  public String Baz {
    get;
    set;
  }

  public override Boolean Equals(Object other) {
    Foo otherFoo = other as Foo;
    return otherFoo != null
      && Bar.Equals(otherFoo.Bar)
      && Baz.Equals(otherFoo.Baz);
  }

  public override Int32 GetHashCode() {
    return Bar.GetHashCode() ^ Baz.GetHasCode();
  }

}

オーバーライドするのではなくEquals、インスタンスのプロパティをプロパティごとに比較したいだけの場合は、リフレクションを使用できます。

public static Boolean AreEqual<T>(T a, T b) {
  foreach (PropertyInfo propertyInfo in typeof(T).GetProperties())
    if (!Object.Equals(propertyInfo.GetValue(a, null),
                       propertyInfo.GetValue(b, null)))
      return false;
  return true;
}
于 2009-08-25T11:12:49.997 に答える