C#: Как был бы Вы модульный тест GetHashCode?

Можно использовать его для переопределения && и || операторы.

&& и || операторы не могут быть переопределены, но если Вы переопределяете |, &, true и false точно правильным способом, которым компилятор будет звонить | и &, когда Вы запишете || и &&.

, Например, посмотрите на этот код (от [1 113] http://ayende.com/blog/1574/nhibernate-criteria-api-operator-overloading - где я узнал об этом приеме; заархивированная версия @BiggsTRC):

public static AbstractCriterion operator &(AbstractCriterion lhs, AbstractCriterion rhs)
{
       return new AndExpression(lhs, rhs);
}

public static AbstractCriterion operator |(AbstractCriterion lhs, AbstractCriterion rhs)
{
       return new OrExpression(lhs, rhs);
}

public static bool operator false(AbstractCriterion criteria)
{
       return false;
}
public static bool operator true(AbstractCriterion criteria)
{
       return false;
}

Это - очевидно, побочный эффект а не способ, которым он предназначается, чтобы использоваться, но это полезно.

31
задан jason 16 December 2009 в 19:47
поделиться

6 ответов

Проверить, что два разных объекта, которые равны, имеют одинаковый хэш-код (для разных значений). Убедитесь, что неодинаковые объекты дают разные хэш-коды, изменяя один аспект / свойство за раз. Хотя в хэш-кодах нет , чтобы отличаться, вам действительно не повезет, если вы выберете разные значения для свойств, которые случаются , чтобы дать один и тот же хеш-код, если у вас нет ошибка.

36
ответ дан 27 November 2019 в 22:19
поделиться

Это было бы похоже на Equals (). Вам нужно убедиться, что два «одинаковых» объекта имеют по крайней мере один и тот же хэш-код. Это означает, что если .Equals () возвращает истину, хэш-коды также должны быть идентичными. Что касается правильных значений хэш-кода, это зависит от того, как вы хешируете.

5
ответ дан 27 November 2019 в 22:19
поделиться

Из личного опыта. Помимо очевидных вещей, таких как одни и те же объекты, дающие вам одинаковые хэш-коды, вам необходимо создать достаточно большой массив уникальных объектов и подсчитать среди них уникальные хэш-коды. Если уникальные хэш-коды составляют менее, скажем, 50% от общего количества объектов, то у вас проблемы, так как ваша хеш-функция не работает.

        List<int> hashList = new List<int>(testObjectList.Count);
        for (int i = 0; i < testObjectList.Count; i++)
        {
            hashList.Add(testObjectList[i]);
        }

        hashList.Sort();
        int differentValues = 0;
        int curValue = hashList[0];
        for (int i = 1; i < hashList.Count; i++)
        {
            if (hashList[i] != curValue)
            {
                differentValues++;
                curValue = hashList[i];
            }
        }

        Assert.Greater(differentValues, hashList.Count/2);
3
ответ дан 27 November 2019 в 22:19
поделиться

Я бы заранее предоставил известный / ожидаемый хэш и сравнил бы результат GetHashCode.

0
ответ дан 27 November 2019 в 22:19
поделиться

Вы создаете отдельные экземпляры с одинаковым значением и проверяете, что GetHashCode для экземпляров возвращает одно и то же значение, и что повторные вызовы одного и того же экземпляра возвращают то же значение.

единственное требование для работы хеш-кода. Для хорошей работы хэш-коды, конечно, должны иметь хорошее распределение, но для этого требуется много тестирования ...

0
ответ дан 27 November 2019 в 22:19
поделиться

Gallio / MbUnit v3.2 поставляется с удобными верификаторами контрактов, которые могут тестировать вашу реализацию GetHashCode () и IEquatable . В частности, вас могут заинтересовать EqualityContract и HashCodeAcceptanceContract . См. здесь , здесь и там для получения более подробной информации.

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

Затем вы объявляете свой верификатор контракта следующим образом:

[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))
  };
}
10
ответ дан 27 November 2019 в 22:19
поделиться
Другие вопросы по тегам:

Похожие вопросы: