NUnit AreEqual всегда возвращает false - PullRequest
0 голосов
/ 09 октября 2010

Я уверен, что упустил что-то простое здесь, но я не могу понять, почему мой тест сравнения объектов NUnit продолжает проваливаться.

У меня есть простой объект:

 public virtual int Id { get; private set; }

    public virtual string Description { get; set; }

    public virtual string Address { get; set; }

    public virtual string Ports { get; set; }

    public virtual string Password { get; set; }        

    public virtual ServerGroup ServerGroup { get; set; }

Я сохраняю экземпляр этого объекта в моей базе данных, а затем извлекаю его с помощью NHibernate. Мой модульный тест NUnit сравнивает сохраненный объект с полученным объектом и сравнивает их. Я понимаю, что AreSame () потерпит неудачу, поскольку они не являются той же ссылкой на объект, но я ожидаю, что AreEqual () пройдет.

Если я отлаживаю тест, я вижу, что оба объекта имеют одинаковые значения в этих свойствах, но мой тест по-прежнему не проходит. Может кто-нибудь сказать мне, почему?

Спасибо!

Ответы [ 3 ]

4 голосов
/ 09 октября 2010

Вы должны переопределить метод Equals() в вашем классе. В противном случае NUnit будет использовать базовую реализацию, которая сравнивает ссылки (что, конечно, не то, что вам нужно)

1 голос
/ 30 октября 2010

Как и предполагалось, вам нужно переопределить Equals. Вам нужно знать о побочных эффектах.

Вам также следует переопределить GetHashCode, иначе вы можете получить объекты, для которых значение .Equals будет истинным, но при использовании вашего класса Id в качестве ключа в словаре хеш не будет совпадать, что приведет к нескольким записям с "равными" идентификаторами. *

Кроме того, вам необходимо переопределить операторы == и! = Для поддержания согласованного поведения.

Представьте себе путаницу, если .Equals были правдой, но == были ложными.

0 голосов
/ 10 октября 2010

Вам нужно необходимо переопределить Equals, как предполагает Грзенио, но следите за тонким источником путаницы, которая может возникнуть с NHibernate.В частности, если включена отложенная загрузка, проверка сравнения типов может завершиться неудачей.Для иллюстрации приведем фрагмент хорошо написанного метода Equals:

    // override object.Equals
    public override bool Equals(object obj)
    {
        //       
        // See the full list of guidelines at
        //   http://go.microsoft.com/fwlink/?LinkID=85237  
        // and also the guidance for operator== at
        //   http://go.microsoft.com/fwlink/?LinkId=85238
        //

        if (GetType() != obj.GetType())
        {
            return false;
        }
        ....
    }

Но когда включена отложенная загрузка, NHib работает так, чтобы сгенерировать прокси фактического объекта (таким образом откладывая ненужные обращения к базе данных).,Если выполняется проверка на равенство между одним объектом, который был «проксифицирован» NHib, и другим, который не был, это приведет к сбою из-за несоответствия типов.Решение (любезно предоставленное проектом S # arp Architecture ) состоит в том, чтобы изменить тип теста таким образом:

public override bool Equals(object obj) {
    ...
    if (GetType() != obj.GetTypeUnproxied())
    {
        return false;
    }
       ...
 }

protected virtual Type GetTypeUnproxied() { return GetType(); }

. Это эффективно возвращает тип базового объекта во всехслучаи, даже когда объект CompareTo является прокси-сервером NHib.

Метод Equals может быть настолько сложным, насколько это важно для правильного выбора, поэтому в идеале вы можете включить его в некоторый вид супертипа слоя (Fowler).Множество проектов с открытым исходным кодом, включая S # arp, который я упоминал ранее, предоставляют примеры того, как это сделать.

HTH,
Berryl

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...