Я пытаюсь утверждать, что один объект «равен» другому объекту.
Объекты - это просто экземпляры класса с множеством общедоступных свойств. Есть ли простой способ заставить NUnit утверждать равенство на основе свойств?
Это мое текущее решение, но я думаю, что может быть что-то получше:
Assert.AreEqual(LeftObject.Property1, RightObject.Property1)
Assert.AreEqual(LeftObject.Property2, RightObject.Property2)
Assert.AreEqual(LeftObject.Property3, RightObject.Property3)
...
Assert.AreEqual(LeftObject.PropertyN, RightObject.PropertyN)
То, что я собираюсь сделать, будет в том же духе, что и CollectionEquivalentConstraint, в котором NUnit проверяет идентичность содержимого двух коллекций.
источник
IEnumerable
он будет сравниваться как коллекция, независимо от реализации переопределения,Equals
поскольку NUnit даетIEnumerable
более высокий приоритет. См. Подробности вNUnitEqualityComparer.AreEqual
методах. Вы можете переопределить компаратор, используя один изUsing()
методов ограничения равенства . Даже в этом случае недостаточно реализовать неуниверсальныйIEqualityComparer
из-за адаптера, который использует NUnit.GetHashCode()
изменяемых типов приведет к неправильному поведению, если вы когда-либо будете использовать этот объект в качестве ключа. ИМХО, перекрываяEquals()
,GetHashCode()
и делают объект непреложным только для тестирования не имеет смысла.Если вы не можете переопределить Equals по какой-либо причине, вы можете создать вспомогательный метод, который выполняет итерацию по общедоступным свойствам путем отражения и утверждает каждое свойство. Что-то вроде этого:
источник
Не переопределяйте Equals только в целях тестирования. Это утомительно и влияет на логику предметной области. Вместо,
Используйте JSON для сравнения данных объекта
Никакой дополнительной логики на ваших объектах. Никаких лишних заданий на тестирование.
Просто воспользуйтесь этим простым методом:
Вроде отлично получается. Информация о результатах выполнения теста покажет сравнение строк JSON (граф объектов), чтобы вы могли сразу увидеть, что не так.
Также обратите внимание! Если у вас есть более крупные сложные объекты и вы просто хотите сравнить их части, вы можете ( использовать LINQ для данных последовательности ) создать анонимные объекты для использования с вышеуказанным методом.
источник
Попробуйте библиотеку FluentAssertions:
http://www.fluentassertions.com/
Его также можно установить с помощью NuGet.
источник
actual.ShouldBeEquivalentTo(expected, x => x.ExcludingMissingMembers())
Я предпочитаю не переопределять Equals только для включения тестирования. Не забывайте, что если вы переопределяете Equals, вам действительно следует также переопределить GetHashCode, иначе вы можете получить неожиданные результаты, например, если используете свои объекты в словаре.
Мне нравится подход к отражению, описанный выше, поскольку он учитывает добавление свойств в будущем.
Однако для быстрого и простого решения часто проще всего создать вспомогательный метод, который проверяет, равны ли объекты, или реализовать IEqualityComparer в классе, который вы сохраняете закрытым для своих тестов. При использовании решения IEqualityComparer вам не нужно беспокоиться о реализации GetHashCode. Например:
источник
Я пробовал несколько упомянутых здесь подходов. Большинство из них включает сериализацию ваших объектов и сравнение строк. Хотя это очень просто и, как правило, очень эффективно, я обнаружил, что это немного не так, когда у вас есть сбой, и сообщается о чем-то вроде этого:
Выяснить, где различия, по меньшей мере, больно.
С помощью сравнения графов объектов FluentAssertions (т.е.
a.ShouldBeEquivalentTo(b)
) вы получите следующее:Это намного лучше. Получите FluentAssertions сейчас, вы будете рады позже (и если вы проголосуете за это, пожалуйста, также проголосуйте за ответ dkl, где впервые было предложено FluentAssertions).
источник
Я согласен с ChrisYoxall - реализация Equals в вашем основном коде исключительно для целей тестирования нехороша.
Если вы реализуете Equals, потому что этого требует какая-то логика приложения, тогда это нормально, но не загромождайте чистый код, предназначенный только для тестирования (также семантика проверки того же самого для тестирования может отличаться от того, что требуется вашему приложению).
Короче говоря, держите код, предназначенный только для тестирования, вне вашего класса.
Простого неглубокого сравнения свойств с использованием отражения должно быть достаточно для большинства классов, хотя вам может потребоваться рекурсия, если ваши объекты имеют сложные свойства. Если вы следуете ссылкам, остерегайтесь циклических ссылок или аналогичных.
лукавый
источник
Ограничения свойств , добавленные в NUnit 2.4.2, позволяют получить решение, которое более читабельно, чем исходное решение OP, и оно дает гораздо лучшие сообщения об ошибках. Это ни в коем случае не является универсальным, но если вам не нужно делать это для слишком большого количества классов, это очень подходящее решение.
Не такой универсальный, как реализация,
Equals
но он дает гораздо лучшее сообщение об ошибке, чемисточник
Решение Max Wikstrom JSON (см. Выше) имеет для меня наибольший смысл, оно короткое, чистое и, что самое главное, работает. Лично я бы предпочел реализовать преобразование JSON как отдельный метод и поместить assert обратно в модульный тест следующим образом ...
ПОМОЩЬ:
МОДУЛЬНЫЙ ТЕСТ :
К вашему сведению - вам может потребоваться добавить ссылку на System.Web.Extensions в ваше решение.
источник
Это довольно старая ветка, но мне было интересно, есть ли причина, по которой не предлагается ответ
NUnit.Framework.Is.EqualTo
иNUnit.Framework.Is.NotEqualTo
?Такие как:
и
источник
Другой вариант - написать собственное ограничение, реализовав абстрактный
Constraint
класс NUnit . С вспомогательным классом, обеспечивающим небольшой синтаксический сахар, полученный тестовый код будет приятно кратким и читабельным, напримерВ качестве крайнего примера рассмотрим класс, который имеет члены «только для чтения», а не является
IEquatable
, и вы не можете изменить тестируемый класс, даже если бы вы хотели:Контракт для
Constraint
класса требует переопределенияMatches
иWriteDescriptionTo
(в случае несоответствия описание ожидаемого значения), но такжеWriteActualValueTo
имеет смысл переопределение (описание фактического значения):Плюс вспомогательный класс:
Пример использования:
источник
Я бы опирался на ответ @Juanma. Однако я считаю, что это не следует реализовывать с помощью утверждений модульного теста. Это утилита, которая вполне может быть использована в некоторых случаях нетестовым кодом.
Я написал статью по этому поводу http://timoch.com/blog/2013/06/unit-test-equality-is-not-domain-equality/
Мое предложение следующее:
Используя это с NUnit
выдает следующее сообщение о несоответствии.
источник
https://github.com/kbilsted/StatePrinter был написан специально для вывода графов объектов в строковое представление с целью написания простых модульных тестов.
Дано
Вы можете типобезопасным способом и с помощью автозаполнения Visual Studio включать или исключать поля.
источник
Просто установите ExpectedObjects из Nuget, вы можете легко сравнить значение свойства двух объектов, значение каждого объекта коллекции, значение двух составных объектов и частичное сравнение значения свойства по анонимному типу.
У меня есть несколько примеров на github: https://github.com/hatelove/CompareObjectEquals
Вот несколько примеров, которые содержат сценарии сравнения объектов:
Ссылка:
источник
Взгляните на следующую ссылку. Это решение из проекта кода, и я тоже его использовал. Он отлично работает для сравнения объектов.
http://www.codeproject.com/Articles/22709/Testing-Equality-of-Two-Objects?msg=5189539#xx5189539xx
источник
Я закончил написанием простой фабрики выражений:
и просто используйте это:
Это очень полезно, так как мне приходится сравнивать набор таких объектов. И вы можете использовать это сравнение где-нибудь еще :)
Вот суть с примером: https://gist.github.com/Pzixel/b63fea074864892f9aba8ffde312094f
источник
Десериализуйте оба класса и выполните сравнение строк.
РЕДАКТИРОВАТЬ: отлично работает, это результат, который я получаю от NUnit;
ИЗМЕНИТЬ ВТОРОЙ: два объекта могут быть идентичными, но порядок сериализации свойств не совпадает. Следовательно, XML другой. DOH!
ИЗМЕНИТЬ ТРИ: это работает. Я использую его в своих тестах. Но вы должны добавлять элементы в свойства коллекции в том порядке, в котором их добавляет тестируемый код.
источник
Я знаю, что это действительно старый вопрос, но NUnit до сих пор не имеет встроенной поддержки для этого. Однако, если вам нравится тестирование в стиле BDD (ala Jasmine), вы были бы приятно удивлены NExpect ( https://github.com/fluffynuts/NExpect , получите его из NuGet), в котором есть глубокое тестирование равенства. ,
(отказ от ответственности: я являюсь автором NExpect)
источник
Стренить и сравнить две строки
Assert.AreEqual (JSON.stringify (LeftObject), JSON.stringify (RightObject))
источник
источник