xUnit: affirmer que deux List <T> sont égaux?

109

Je suis nouveau sur TDD et xUnit, je veux donc tester ma méthode qui ressemble à quelque chose comme:

List<T> DeleteElements<T>(this List<T> a, List<T> b);

Existe-t-il une méthode Assert que je peux utiliser? Je pense que quelque chose comme ça serait bien

List<int> values = new List<int>() { 1, 2, 3 };
List<int> expected = new List<int>() { 1 };
List<int> actual = values.DeleteElements(new List<int>() { 2, 3 });

Assert.Exact(expected, actual);

Y a-t-il quelque chose comme ça?

Petar Petrov
la source

Réponses:

137

xUnit.Net reconnaît les collections, il vous suffit donc de faire

Assert.Equal(expected, actual); // Order is important

Vous pouvez voir d'autres assertions de collection disponibles dans CollectionAsserts.cs

Pour NUnit , les méthodes de comparaison de collections de bibliothèques sont

CollectionAssert.AreEqual(IEnumerable, IEnumerable) // For sequences, order matters

et

CollectionAssert.AreEquivalent(IEnumerable, IEnumerable) // For sets, order doesn't matter

Plus de détails ici: CollectionAssert

MbUnit a également des assertions de collection similaires à NUnit: Assert.Collections.cs

Konstantin Spirin
la source
1
Lien du code source modifié pour xunit.codeplex.com/SourceControl/changeset/view/…
Julien Roncaglia
1
Nouveau lien dans les commentaires également cassé.
Scott Stafford
1
Le projet est maintenant déplacé vers GitHub, mais je n'ai pas pu y trouver ce fichier source particulier non plus.
MEMark
1
Pour un objet complexe, n'oubliez pas que vous avez besoin d'un Equal + GetHasCode pour que cela fonctionne ou donnez à la méthode Equal un EqulityComparer personnalisé
maracuja-juice
2
La méthode xUnit Equal retourne false pour deux IEnumerables avec un contenu égal.
Vladimir Kocjancic
31

Dans la version actuelle de XUnit (1.5), vous pouvez simplement utiliser

Assert.Equal (attendu, réel);

La méthode ci-dessus effectuera une comparaison élément par élément des deux listes. Je ne suis pas sûr que cela fonctionne pour une version antérieure.

hwiechers
la source
8
Le problème que j'ai rencontré avec Assert.Equal pour les collections est qu'il échoue si les éléments des collections sont dans des ordres différents, même si les éléments sont présents dans les deux.
Scott Lawrence
1
Les listes @ ScottA.Lawrence ont aussi de l'ordre! Obtenez-vous le même comportement avec les HashSets?
johv
@johv Je ne l'ai pas testé avec HashSets, mais c'est une bonne idée. Une fois que j'ai eu l'occasion de l'essayer, j'essaierai de me rappeler de répondre ici.
Scott Lawrence
2
Il semble également échouer si les types de collection sont différents, même s'ils contiennent tous les deux les mêmes éléments dans le même ordre.
James White
3
Mais il a une sortie très merdique. Il ne vous dit pas où deux listes diffèrent! :(
Zordid
17

Avec xUnit, si vous souhaitez sélectionner les propriétés de chaque élément à tester, vous pouvez utiliser Assert.Collection.

Assert.Collection(elements, 
  elem1 => Assert.Equal(expect1, elem1.SomeProperty),
  elem2 => { 
     Assert.Equal(expect2, elem2.SomeProperty);
     Assert.True(elem2.TrueProperty);
  });

Cela teste le nombre attendu et garantit que chaque action est vérifiée.

Drew Williams
la source
2

Récemment, j'utilisais xUnit 2.4.0et des Moq 4.10.1packages dans mon application asp.net core 2.2.

Dans mon cas, j'ai réussi à le faire fonctionner avec un processus en deux étapes:

  1. Définition d'une implémentation de IEqualityComparer<T>

  2. Passez l'instance de comparateur comme troisième paramètre dans la Assert.Trueméthode:

    Assert.True(expected, actual, new MyEqualityComparer());

Mais il existe un autre moyen plus agréable d'obtenir le même résultat en utilisant le package FluentAssertions . Il vous permet d'effectuer les opérations suivantes:

// Assert          
expected.Should().BeEquivalentTo(actual));

Fait intéressant, cela Assert.Equal()échoue toujours même lorsque j'ai commandé les éléments de deux listes pour les mettre dans le même ordre.

Dmitry Stepanov
la source
2
quelque chose ne va pas avec votre commande BeEquivalentTo ne se soucie pas de la commande (c'est pourquoi votre test passe avec BeEquivalentTo et non avec assert.Equal)
RagnaRock