36 votes

CollectionAssert utiliser avec des génériques?

Il semble que l' CollectionAssert ne peut pas être utilisé avec les médicaments génériques. C'est super frustrant, le code que je veux tester ne utiliser des génériques. Que dois-je faire? Écrire réutilisable pour convertir entre les deux? Manuellement, vérifiez les collection d'équivalence?

Cette échoue:

ICollection<IDictionary<string, string>> expected = // ...

IEnumerable<IDictionary<string, string>> actual = // ...

// error 1 and 2 here
CollectionAssert.AreEqual(expected.GetEnumerator().ToList(), actual.ToList());

// error 3 here
Assert.IsTrue(expected.GetEnumerator().SequenceEquals(actual));

Les erreurs de compilation:

Erreur 1:

'Système.Les Collections.Génériques.IEnumerator>' ne contient pas une définition pour 'ToList' et aucune méthode d'extension 'ToList' acceptant un premier argument de type 'System.Les Collections.Génériques.IEnumerator>' a pu être trouvé

Erreur 2

'Système.Les Collections.Génériques.IEnumerator>' ne contient pas une définition pour 'ToList' et aucune méthode d'extension 'ToList' acceptant un premier argument de type 'System.Les Collections.Génériques.IEnumerator>' a pu être trouvé

Erreur 3

'Système.Les Collections.Génériques.IEnumerator>' ne contient pas une définition pour 'SequenceEquals' et aucune méthode d'extension 'SequenceEquals' acceptant un premier argument de type 'System.Les Collections.Génériques.IEnumerator>' a pu être trouvé

Ce que je fais mal? Je ne suis pas à l'utilisation des extensions correctement?

Mise à jour: Ok, cela ressemble un peu mieux, mais ne fonctionne toujours pas:

IEnumerable<IDictionary<string, string>> expected = // ...

IEnumerable<IDictionary<string, string>> actual = // ...

CollectionAssert.AreEquivalent(expected.ToList(), actual.ToList()); // fails
CollectionAssert.IsSubsetOf(expected.ToList(), actual.ToList()); // fails

Je ne veux pas être la comparaison des listes; je ne se soucient définir l'appartenance de l'égalité. L'ordre des membres est sans importance. Comment puis-je contourner ce problème?

40voto

Mark Seemann Points 102767

Vous pouvez utiliser CollectionAssert générique de collections. Le truc, c'est de comprendre que la CollectionAssert méthodes fonctionnent sur ICollection, et bien que quelques génériques de collecte des interfaces de mettre en oeuvre ICollection, List<T> n'.

Ainsi, vous pouvez contourner cette limitation en utilisant l' ToList méthode d'extension:

IEnumerable<Foo> expected = //...
IEnumerable<Foo> actual = //...
CollectionAssert.AreEqual(expected.ToList(), actual.ToList());

Cela dit, je considère toujours CollectionAssert cassé en a beaucoup d'autres façons, j'ai donc tendance à utiliser Assert.IsTrue avec l'extension LINQ méthodes, comme ceci:

Assert.IsTrue(expected.SequenceEquals(actual));

FWIW, je suis actuellement à l'aide de ces méthodes d'extension pour effectuer d'autres comparaisons:

public static class EnumerableExtension
{
    public static bool IsEquivalentTo(this IEnumerable first, IEnumerable second)
    {
        var secondList = second.Cast<object>().ToList();
        foreach (var item in first)
        {
            var index = secondList.FindIndex(item.Equals);
            if (index < 0)
            {
                return false;
            }
            secondList.RemoveAt(index);
        }
        return secondList.Count == 0;
    }

    public static bool IsSubsetOf(this IEnumerable first, IEnumerable second)
    {
        var secondList = second.Cast<object>().ToList();
        foreach (var item in first)
        {
            var index = secondList.FindIndex(item.Equals);
            if (index < 0)
            {
                return false;
            }
            secondList.RemoveAt(index);
        }
        return true;
    }
}

6voto

Sudipta Points 31

Si vous travaillez avec des ensembles, utilisez cet idiome

 HashSet<string> set1  = new HashSet<string>(){"A","B"};
HashSet<string> set2  = new HashSet<string>(){"B","A"};

Assert.IsTrue(set1.SetEquals(set2));
 

1voto

John Saunders Points 118808

Vous pouvez facilement écrire votre propre version générique, puis la déplacer vers une classe de base ou d’utilitaire utilisée dans tous vos tests. Basez-vous sur les opérateurs LINQ comme All and Any.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X