J'essaye d'affirmer qu'un objet est "égal" à un autre objet.
Les objets ne sont que des instances d'une classe avec un tas de propriétés publiques. Existe-t-il un moyen simple de faire affirmer l'égalité par NUnit en fonction des propriétés?
C'est ma solution actuelle mais je pense qu'il y a peut-être quelque chose de mieux:
Assert.AreEqual(LeftObject.Property1, RightObject.Property1)
Assert.AreEqual(LeftObject.Property2, RightObject.Property2)
Assert.AreEqual(LeftObject.Property3, RightObject.Property3)
...
Assert.AreEqual(LeftObject.PropertyN, RightObject.PropertyN)
Ce que je veux serait dans le même esprit que le CollectionEquivalentConstraint dans lequel NUnit vérifie que le contenu de deux collections est identique.
la source
IEnumerable
il sera comparé en tant que collection indépendamment des implémentations deEquals
substitution, car NUnit donneIEnumerable
une priorité plus élevée. Voir lesNUnitEqualityComparer.AreEqual
méthodes pour plus de détails. Vous pouvez remplacer le comparateur à l'aide de l'une desUsing()
méthodes de la contrainte d'égalité . Même dans ce cas, il n'est pas suffisant d'implémenter le non générique enIEqualityComparer
raison de l'adaptateur utilisé par NUnit.GetHashCode()
en œuvre sur des types mutables se comportera mal si jamais vous utilisez cet objet comme clé. À mon humble avis, remplaçantEquals()
,GetHashCode()
et de faire l'objet immuable de juste pour tester n'a pas de sens.Si vous ne pouvez pas remplacer Equals pour une raison quelconque, vous pouvez créer une méthode d'assistance qui itère à travers les propriétés publiques par réflexion et affirmer chaque propriété. Quelque chose comme ça:
la source
Ne remplacez pas Equals uniquement à des fins de test. C'est fastidieux et affecte la logique du domaine. Au lieu,
Utilisez JSON pour comparer les données de l'objet
Aucune logique supplémentaire sur vos objets. Aucune tâche supplémentaire pour les tests.
Utilisez simplement cette méthode simple:
Cela semble bien fonctionner. Les informations sur les résultats du testeur afficheront la comparaison de chaînes JSON (le graphique d'objet) incluse afin que vous voyiez directement ce qui ne va pas.
Notez également! Si vous avez des objets complexes plus volumineux et que vous souhaitez simplement en comparer des parties, vous pouvez ( utilisez LINQ pour les données de séquence ) créer des objets anonymes à utiliser avec la méthode ci-dessus.
la source
Essayez la bibliothèque FluentAssertions:
http://www.fluentassertions.com/
Il peut également être installé à l'aide de NuGet.
la source
actual.ShouldBeEquivalentTo(expected, x => x.ExcludingMissingMembers())
Je préfère ne pas remplacer Equals juste pour activer les tests. N'oubliez pas que si vous remplacez Equals, vous devez vraiment remplacer GetHashCode ou vous pouvez obtenir des résultats inattendus si vous utilisez vos objets dans un dictionnaire par exemple.
J'aime l'approche de réflexion ci-dessus car elle permet l'ajout de propriétés à l'avenir.
Pour une solution simple et rapide, il est souvent plus simple de créer une méthode d'assistance qui teste si les objets sont égaux ou d'implémenter IEqualityComparer sur une classe que vous gardez privée pour vos tests. Lorsque vous utilisez la solution IEqualityComparer, vous n'avez pas besoin de vous soucier de l'implémentation de GetHashCode. Par exemple:
la source
J'ai essayé plusieurs approches mentionnées ici. La plupart impliquent la sérialisation de vos objets et une comparaison de chaînes. Bien que super facile et généralement très efficace, j'ai trouvé que cela arrivait un peu court lorsque vous avez un échec et que quelque chose comme ça est signalé:
Déterminer où se trouvent les différences est pour le moins pénible.
Avec les comparaisons de graphes d'objets de FluentAssertions (ie
a.ShouldBeEquivalentTo(b)
), vous récupérez ceci:C'est beaucoup mieux. Obtenez FluentAssertions maintenant, vous serez heureux plus tard (et si vous votez pour cela, veuillez également voter pour la réponse de dkl où FluentAssertions a été suggéré pour la première fois).
la source
Je suis d'accord avec ChrisYoxall - implémenter Equals dans votre code principal uniquement à des fins de test n'est pas bon.
Si vous implémentez Equals parce que certaines logiques d'application l'exigent, c'est très bien, mais évitez d'encombrer le code de test uniquement (la sémantique de la vérification de la même chose pour les tests peut également être différente de celle requise par votre application).
En bref, gardez le code de test uniquement hors de votre classe.
Une simple comparaison superficielle des propriétés à l'aide de la réflexion devrait suffire pour la plupart des classes, même si vous devrez peut-être répéter si vos objets ont des propriétés complexes. Si vous suivez des références, méfiez-vous des références circulaires ou similaires.
Sournois
la source
Les contraintes de propriété , ajoutées dans NUnit 2.4.2, permettent une solution plus lisible que celle d'origine de l'OP, et elle produit de bien meilleurs messages d'échec. Ce n'est en aucun cas générique, mais si vous n'avez pas besoin de le faire pour trop de classes, c'est une solution très adéquate.
Pas aussi général que la mise en œuvre,
Equals
mais cela donne un bien meilleur message d'échec quela source
La solution JSON de Max Wikstrom (ci-dessus) est la plus logique pour moi, elle est courte, propre et surtout elle fonctionne. Personnellement, je préfère implémenter la conversion JSON en tant que méthode distincte et replacer l'assertion dans le test unitaire comme ceci ...
MÉTHODE D'AIDE:
TEST DE L'UNITÉ :
FYI - Vous devrez peut-être ajouter une référence à System.Web.Extensions dans votre solution.
la source
C'est un fil assez ancien, mais je me demandais s'il y avait une raison pour laquelle aucune réponse n'est proposée
NUnit.Framework.Is.EqualTo
etNUnit.Framework.Is.NotEqualTo
?Tel que:
et
la source
Une autre option consiste à écrire une contrainte personnalisée en implémentant la
Constraint
classe abstraite NUnit . Avec une classe d'assistance pour fournir un peu de sucre syntaxique, le code de test résultant est agréablement concis et lisible, par exemplePour un exemple extrême, considérez la classe qui a des membres en lecture seule, n'est pas
IEquatable
, et vous ne pourriez pas changer la classe testée même si vous vouliez:Le contrat pour la
Constraint
classe exige que l'on remplaceMatches
etWriteDescriptionTo
(dans le cas d'une discordance, un récit pour la valeur attendue), mais aussi le dépassementWriteActualValueTo
(récit pour la valeur réelle) a du sens:Plus la classe d'assistance:
Exemple d'utilisation:
la source
Je miserais sur la réponse de @Juanma. Cependant, je pense que cela ne devrait pas être implémenté avec des assertions de test unitaire. C'est un utilitaire qui pourrait très bien être utilisé dans certaines circonstances par du code non test.
J'ai écrit un article sur le sujet http://timoch.com/blog/2013/06/unit-test-equality-is-not-domain-equality/
Ma proposition est la suivante:
Utilisation de ceci avec NUnit
renvoie le message suivant en cas d'incompatibilité.
la source
https://github.com/kbilsted/StatePrinter a été écrit spécifiquement pour vider les graphiques d'objets en représentation sous forme de chaîne dans le but d'écrire des tests unitaires faciles.
Donné
Vous pouvez en toute sécurité et en utilisant la saisie semi-automatique de Visual Studio inclure ou exclure des champs.
la source
Installez simplement ExpectedObjects à partir de Nuget, vous pouvez facilement comparer la valeur de propriété de deux objets, chaque valeur d'objet de la collection, la valeur de deux objets composés et la valeur de propriété de comparaison partielle par type anonyme.
J'ai quelques exemples sur github: https://github.com/hatelove/CompareObjectEquals
Voici quelques exemples contenant des scénarios de comparaison d'objets:
Référence:
la source
Jetez un œil au lien suivant. C'est une solution de projet de code et je l'ai aussi utilisée. Cela fonctionne très bien pour comparer les objets.
http://www.codeproject.com/Articles/22709/Testing-Equality-of-Two-Objects?msg=5189539#xx5189539xx
la source
J'ai fini par écrire une simple fabrique d'expressions:
et utilisez-le simplement:
C'est très utile car je dois comparer la collection de tels objets. Et vous pouvez utiliser ce comparateur ailleurs :)
Voici l'essentiel de l'exemple: https://gist.github.com/Pzixel/b63fea074864892f9aba8ffde312094f
la source
Désérialisez les deux classes et effectuez une comparaison de chaînes.
EDIT: Fonctionne parfaitement, c'est la sortie que j'obtiens de NUnit;
MODIFIER DEUX: Les deux objets peuvent être identiques, mais l'ordre dans lequel les propriétés sont sérialisées n'est pas le même. Par conséquent, le XML est différent. DOH!
EDIT TROIS: Cela fonctionne. Je l'utilise dans mes tests. Mais vous devez ajouter des éléments aux propriétés de la collection dans l'ordre dans lequel le code testé les ajoute.
la source
Je sais que c'est une question très ancienne, mais NUnit n'a toujours pas de support natif pour cela. Cependant, si vous aimez les tests de style BDD (ala Jasmine), vous serez agréablement surpris par NExpect ( https://github.com/fluffynuts/NExpect , obtenez-le de NuGet), qui a des tests d'égalité profonds cuits ici .
(avertissement: je suis l'auteur de NExpect)
la source
Stringifier et comparer deux chaînes
Assert.AreEqual (JSON.stringify (LeftObject), JSON.stringify (RightObject))
la source
la source