4

私の現在のプロジェクトでは、いくつかの IEqualitycomparers があります。
これらは、オブジェクトのいくつかのプロパティを取り、それらを比較します。
プロパティは、値とnullの両方に対して、等しいか異なるかのいずれかです。

これらを単体テストしたいのですが、さまざまな可能性はすべて正気ではありません。これらを効率的にテストするにはどうすればよいですか?

更新
現在、それらは entlib のデータ ブロックで満たされているため、コンストラクターではなくプロパティを介して値を取得します。

例(vb.netでは、C#も話します):

Public Class GuarantyEqualityComparer
    Implements IEqualityComparer(Of Guaranty)

    Public Overloads Function Equals(x As Guaranty, y As Guaranty) As Boolean Implements IEqualityComparer(Of Guaranty).Equals
        Return x.ClientCode = y.ClientCode AndAlso x.LocationCode = y.LocationCode AndAlso x.CategoryCode = y.CategoryCode AndAlso x.GuarantyCode = y.GuarantyCode
    End Function

    Public Overloads Function GetHashCode(obj As Guaranty) As Integer Implements IEqualityComparer(Of Guaranty).GetHashCode
        Const format As String = "{0}{1}{2}{3}"
        Return String.Format(CultureInfo.InvariantCulture, format, obj.ClientCode, obj.LocationCode, obj.CategoryCode, obj.GuarantyCode).GetHashCode()
    End Function
End Class
4

1 に答える 1

3

さて、コンストラクターを持つ可能性があることを考えると、各コンストラクターパラメーターのサンプル値を指定できるユーティリティクラスを作成しようとします:

var comparer = new GuarantyEqualityComparer();
var tester = EqualityTester<Guaranty>.CreateBuilder(comparer)
                 .AddValue("ClientCode", "Sample1", "Sample2", null)
                 .AddValue("LocationCode", 1, 3, 0)
                 .Builder();
tester.Test();

テスターは、考えられる順列をすべて調べて、少なくとも以下をチェックします。

  • x.Equals(y)xyが同じ値で作成されたとき
  • x.GetHashCode() == y.GetHashCode()xyが同じ値で作成されたとき
  • !x.Equals(y)xyが異なる値で構築された時期

また、とが異なる値でいつ構築されたかを確認することもできます。これはのコントラクトでは必要ありません。優れたハッシュ コードでさえ、(可能な値が 2 32を超える任意の型の場合) 失敗する場合が常にありますが、それでも妥当な健全性チェックになります。通常はコードが正しいときに失敗したサンプル値を選択するのは非常に不運です。x.GetHashCode() != y.GetHashCode()xyGetHashCode


ハッシュ コードの生成に関しては、私は常に次のようなものを使用します。

int hash = 19;
hash = hash * 31 + HashOfField1;
hash = hash * 31 + HashOfField2;
...
return hash;

Noda Time の場合、次のようなメソッドを可能にするヘルパー クラスにいくつかあります。

public override int GetHashCode()
{
    int hash = HashCodeHelper.Initialize();
    hash = HashCodeHelper.Hash(hash, LocalInstant);
    hash = HashCodeHelper.Hash(hash, Offset);
    hash = HashCodeHelper.Hash(hash, Zone);
    return hash;
}

ヘルパーは nullity を処理します。これはすべて、ハッシュ コードを計算する必要があるたびに書式設定によって文字列を作成するよりもはるかに優れています。

于 2013-01-17T10:39:25.870 に答える