Comment affirmer que deux liste contient des éléments avec les mêmes propriétés publiques dans NUnit?
Je tiens à affirmer que les éléments de deux liste contient les valeurs que j'ai prévu, quelque chose comme:
var foundCollection = fooManager.LoadFoo();
var expectedCollection = new List<Foo>()
{
new Foo() { Bar = "a", Bar2 = "b" },
new Foo() { Bar = "c", Bar2 = "d" }
};
//assert: I use AreEquivalent since the order does not matter
CollectionAssert.AreEquivalent(expectedCollection, foundCollection);
Cependant le code ci-dessus ne fonctionnent pas (je suppose parce que .Equals() ne retourne pas vrai pour les différents objets avec la même valeur). Dans mon test, je ne se soucient de la propriété publique de valeurs, pas de savoir si les objets sont égaux. Que puis-je faire pour que mon affirmation?
Vous devez vous connecter pour publier un commentaire.
RETRAVAILLÉ RÉPONSE
Il y a un
CollectionAssert.AreEqual(IEnumerable, IEnumerable, IComparer)
de la surcharge d'affirmer que deux collections contiennent les mêmes objets dans le même ordre, à l'aide d'unIComparer
mise en œuvre pour vérifier l'objet d'équivalence.Dans le scénario décrit ci-dessus, l'ordre n'est pas important. Toutefois, suffisamment à gérer aussi la situation où il y a plusieurs équivalent des objets dans les deux collections, il devient nécessaire de premier ordre des objets dans chaque collecte et l'utilisation de l'une-par-une comparaison pour s'assurer que le nombre d'équivalent objets sont les mêmes dans les deux collections.
Enumerable.OrderBy
fournit une surcharge qui prend unIComparer<T>
argument. Pour s'assurer que les deux collections sont triés dans le même ordre, il est plus ou moins nécessaire que les types de l'identification des propriétés de mettre en œuvreIComparable
. Voici un exemple de comparer la classe qui implémente à la fois laIComparer
etIComparer<Foo>
interfaces, et où il est supposé queBar
l'emporte lors de la commande:À affirmer que les objets dans les deux collections sont de même et vient en nombre égal (mais pas nécessairement dans le même ordre pour commencer), les lignes suivantes devraient faire l'affaire:
Intersect
expression ne serait pas réagir correctement à l'exemple de Louis a donné ({A, A, B} et {A, B, B}), droit? LeIntersect
serait de trouver des correspondances pour l'ensemble de ses trois objets dans la deuxième collection et donc de revenir à la pleine longueur, même si le nombre de A:s et B:s sont différents dans les deux collections, droit?Equals()
méthode consiste à substituer pour laFoo
classe déjà, peut-on utiliser.AreEqual(ICollection, ICollection)
Directement?Non, NUnit n'a pas de mécanisme en question de l'état actuel. Vous devrez supprimer votre propre affirmation de la logique. Soit en tant que distincte de la méthode, ou l'utilisation de
Has.All.Matches
:Bien sûr, cela suppose que vous connaissez toutes les propriétés pertinentes à l'avance (sinon,
IsInExpected
devrez recourir à la réflexion) et que l'élément de commande n'est pas pertinent.(Et votre hypothèse était correcte, NUnit collection affirme par défaut utiliser les comparateurs de types, qui dans la plupart des cas d'défini par l'utilisateur, seront l'objet
ReferenceEquals
)À L'Aide De A.Tous les.Matches() fonctionne très bien pour la comparaison d'une trouvé de la collection à la devrait collection. Cependant, il n'est pas nécessaire de définir le prédicat utilisé par l'A.Tous les.Matches() comme une fonction distincte. Pour relativement simples comparaisons, le prédicat peut être inclus en tant que partie de l'expression lambda comme ça.
Maintenant, alors que cette assertion s'assurer que chaque entrée dans le trouvé collection existe aussi dans le devrait collection, il ne prouve pas l'inverse, à savoir que chaque entrée dans le devrait collection est contenue dans le trouvé collection. Donc, quand il est important de savoir que trouvé et devrait contiennent sont sémantiquement équivalentes (c'est à dire, ils contiennent les mêmes sémantiquement équivalent entrées), on doit ajouter une affirmation supplémentaire.
Le plus simple choix est d'ajouter le suivant.
Pour ceux qui préfèrent un plus gros marteau, de l'affirmation suivante pourrait être utilisée à la place.
En utilisant la première assertion ci-dessus en association avec le deuxième (de préférence) ou de troisième affirmation, nous avons maintenant prouvé que les deux collections sont sémantiquement identiques.
Avez-vous essayé quelque chose comme cela?
Pour effectuer equivilance opérations sur des types complexes vous avez besoin pour mettre en œuvre IComaprable.
http://support.microsoft.com/kb/320727
Vous pouvez également utiliser récursive de réflexion, ce qui est moins souhaitable.
Une option consiste à écrire personnalisé contraintes de comparer les éléments. Voici un bel article sur le sujet: http://www.davidarno.org/2012/07/25/improving-nunit-custom-constraints-with-syntax-helpers/
J'ai eu un problème similaire. Liste des contributeurs, qui contient des "commentateurs" et d'autres ppl... je veux obtenir tous les commentaires et de qui proviennent les créateurs, mais je suis ofc seulement intéressés par des créateurs uniques. Si quelqu'un a créé 50 commentaires je ne veux que son nom apparaît qu'une fois. Alors, j'ai écrit un test pour voir que les commentateurs sont int la GetContributors() résultat.
J'ai peut-être tort, mais ce que je pense de votre après (ce que j'ai est après, quand j'ai trouvé ce post), c'est affirmer qu'il y a exactement un de chaque élément dans une collection, trouve dans une autre collection.
J'ai résolu ce problème comme suit:
Si vous aussi vous voulez la liste résultante de ne pas contenir d'autres éléments que prévu, vous pouvez simplement comparer la longueur des listes ainsi..
J'espère que c'est utile, si oui, je serais très reconnaissant si vous dirais ma réponse.
Je déconseille l'utilisation de la réflexion ou quoi que ce soit complexe, il ajoute juste plus de travail/maintenace.
Sérialiser l'objet (je recommande json) et de la chaîne de les comparer.
Je ne suis pas sûr pourquoi vous vous opposez à l'ordre, mais je voudrais encore vous recommandons de comme il vous fera économiser une coutume de comparer pour chaque type.
Et il fonctionne automatiquement avec le domaine des objets.
Exemple (SharpTestsEx de courant)
Vous pouvez l'écrire comme un simple extensions et de le rendre plus lisible.
et puis, à l'aide de votre exemple de l'appeler comme ceci:
Vous obtiendrez un message d'assertion comme suit:
...:"un","Bar2":"b"},{"Bar":"d","Bar2":"d"}]
...:"un","Bar2":"b"},{"Bar":"c","Bar2":"d"}]
...__________________^_____
Code Simple expliquant comment utiliser l'interface IComparer