Dans l'un de mes tests, je veux m'assurer qu'une collection contient certains éléments. Par conséquent, je souhaite comparer cette collection avec les éléments d’une collection attendue et non en ce qui concerne l’ordre des éléments . Actuellement, mon code de test ressemble à ceci:
[Fact]
public void SomeTest()
{
// Do something in Arrange and Act phase to obtain a collection
List<int> actual = ...
// Now the important stuff in the Assert phase
var expected = new List<int> { 42, 87, 30 };
Assert.Equal(expected.Count, actual.Count);
foreach (var item in actual)
Assert.True(expected.Contains(item));
}
Existe-t-il un moyen plus simple de réaliser cela dans xunit.net? Je ne peux pas utiliser Assert.Equal
car cette méthode vérifie si l'ordre des éléments est le même dans les deux collections. J'ai jeté un oeil à Assert.Collection
mais cela ne supprime pas l'instruction Assert.Equal(expected.Count, actual.Count)
dans le code ci-dessus.
Merci pour vos réponses à l'avance.
Brad Wilson de xunit.net m'a dit dans cette Problème Github qu'il fallait utiliser l'opérateur OrderBy
de LINQ et ensuite Assert.Equal
pour vérifier que deux collections contiennent des éléments égaux sans égard à leur ordre. Bien sûr, vous auriez besoin d'une propriété sur la classe d'élément correspondante que vous pouvez utiliser pour commander en premier lieu (ce que je n'avais pas vraiment dans mon cas).
Personnellement, j'ai résolu ce problème en utilisant FluentAssertions , une bibliothèque fournissant de nombreuses méthodes d'assertion pouvant être appliquées dans un style fluide. Bien sûr, il existe également de nombreuses méthodes que vous pouvez utiliser pour valider des collections .
Dans le contexte de ma question, j'utiliserais quelque chose comme le code suivant:
[Fact]
public void Foo()
{
var first = new[] { 1, 2, 3 };
var second = new[] { 3, 2, 1 };
first.Should().BeEquivalentTo(second);
}
Ce test réussit car l'appel BeEquivalentTo
ignore l'ordre des éléments.
Shouldly est également une bonne alternative si vous ne voulez pas utiliser FluentAssertions.
Pas une Xunit, mais une réponse Linq:
bool areSame = !expected.Except(actual).Any() && expected.Count == actual.Count;
Donc dans XUnit:
Assert.True(!expected.Except(actual).Any() && expected.Count == actual.Count));
Comme @ robi-y a dit, dans Microsoft.VisualStudio.QualityTools.UnitTestFramework
il y a CollectionAssert.AreEquivalent
Peut-être un autre moyen est:
Assert.True(expected.SequenceEqual(actual));
Cela vérifie aussi la commande. C'est ce qui se passe en interne:
using (IEnumerator<TSource> e1 = first.GetEnumerator())
using (IEnumerator<TSource> e2 = second.GetEnumerator())
{
while (e1.MoveNext())
{
if (!(e2.MoveNext() && comparer.Equals(e1.Current, e2.Current))) return false;
}
if (e2.MoveNext()) return false;
}
return true;
Donc, si vous ne vous souciez pas de l'ordre, il suffit de commander les deux listes avant:
Assert.True(expected.OrderBy(i => i).SequenceEqual(actual.OrderBy(i => i)));
Vous pouvez utiliser CollectionAssert.AreEquivalent
à partir de Microsoft
CollectionAssert.AreEquivalent(expected, actual);