C#:你如何对GetHashCode进行单元测试?

Svi*_*ish 31 c# tdd unit-testing gethashcode

测试Equals方法非常简单(据我所知).但是你怎么测试这个GetHashCode方法呢?

Jon*_*eet 36

测试两个相同的对象具有相同的哈希码(对于各种值).检查不相等的对象是否给出不同的哈希码,一次改变一个方面/属性.虽然哈希码不具有有所不同,你会非常不幸的挑选不同的值,其性质发生给相同的哈希代码,除非你有一个错误.

  • 据我所知,单元测试的目的是验证*方法是否正常工作*.GetHashCode的唯一要求是:`如果两个对象比较相等,则每个对象的GetHashCode方法必须返回相同的值.为不同的对象返回不同的值是性能问题:GetHashCode总是返回0是一个严重的性能缺陷,但实际上它仍然是*a*有效*哈希函数.这应该是某种代码审查的主题,而不是单元测试.我对吗? (9认同)
  • 仅仅因为其他人的代码无法生成分布均匀的哈希值并不意味着它不适合您的代码. (7认同)
  • 我想说的是,只有一个测试检查,如果GetHashCode为相同的对象返回相同的值,则应该实现,GetHashCode被用户覆盖并实现. (2认同)

Yan*_*vin 10

Gallio/MbUnit v3.2带有方便的合同验证器,可以测试你的实现GetHashCode()IEquatable<T>.更具体地说,你可能会感兴趣的EqualityContractHashCodeAcceptanceContract.见这里,这里没有更多的细节.

public class Spot
{
  private readonly int x;
  private readonly int y;

  public Spot(int x, int y)
  {
    this.x = x;
    this.y = y;
  }

  public override int GetHashCode()
  {
    int h = -2128831035;
    h = (h * 16777619) ^ x;
    h = (h * 16777619) ^ y;
    return h;
  }
}
Run Code Online (Sandbox Code Playgroud)

然后你声明你的合同验证者:

[TestFixture]
public class SpotTest
{
  [VerifyContract]
  public readonly IContract HashCodeAcceptanceTests = new HashCodeAcceptanceContract<Spot>()
  {
    CollisionProbabilityLimit = CollisionProbability.VeryLow,
    UniformDistributionQuality = UniformDistributionQuality.Excellent,
    DistinctInstances = DataGenerators.Join(Enumerable.Range(0, 1000), Enumerable.Range(0, 1000)).Select(o => new Spot(o.First, o.Second))
  };
}
Run Code Online (Sandbox Code Playgroud)


Dav*_*kle 5

它与Equals()非常相似.您需要确保两个"相同"的对象至少具有相同的哈希码.这意味着如果.Equals()返回true,则哈希码也应该相同.至于正确的哈希码值是什么,这取决于你如何散列.