单元测试GetHashCode,考虑开发人员时间

时间:2013-01-17 08:40:39

标签: .net unit-testing iequalitycomparer

在我目前的项目中,我有几个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

1 个答案:

答案 0 :(得分: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)x使用相同的值构建时,
  • y
  • x.GetHashCode() == y.GetHashCode()x使用相同的值构建时,
  • y
  • !x.Equals(y)x使用不同的值构建时,
  • y

x.GetHashCode() != y.GetHashCode()x使用不同的值构建时, 还可以检查yGetHashCode的合同要求,即使是好的哈希代码总会出现失败的情况(对于任何超过2 32 可能的值)但它仍然是一个合理的健全性检查 - 你通常必须非常不走运,选择在代码正确时失败的样本值。


就哈希码生成而言,我总是使用以下内容:

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

对于Noda Time,我们在helper class中有一些允许这样的方法:

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

帮助程序为您处理无效。所有这些很多比每次需要计算哈希码时通过格式化创建字符串更好。