4

在我目前的项目中,我有几个 IEqualitycomparers。
它们采用对象的几个属性并比较它们。
属性可以是相等的,不同的,这既适用于值,也适用于空值。

我想对这些进行单元测试,但所有不同的可能性都是疯狂的。我怎样才能有效地测试这些?

更新
目前它们通过属性而不是构造函数获取它们的值,因为它们填充了 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)何时x以及y使用不同的值构建

它还可以检查x.GetHashCode() != y.GetHashCode()何时使用不同的值构建x和构建。y不是的合同所要求的GetHashCode,即使是一个好的哈希码也总是会出现失败的情况(对于任何具有超过 2 32 个可能值的类型),但它仍然是一个合理的完整性检查 - 你通常会有当代码正确时选择失败的样本值是非常不幸的。


在哈希码生成方面,我总是使用以下内容:

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

助手为您处理无效性。所有这些都比每次需要计算哈希码时通过格式化创建字符串要好得多

于 2013-01-17T10:39:25.870 回答