2010-01-18 3 views
1

J'essaie de comparer le contenu de 2 collections dans un test unitaire en .NET en utilisant MSTEST. Pour rendre les choses simples, au lieu d'avoir à .Sort() et ensuite faire une boucle dans la collection et comparer les éléments un par un, j'ai trouvé la nouvelle et très cool méthode .Intersect Extension.Méthode d'extension d'intersection, la sensibilité à la casse ne fonctionne pas

Il semble fonctionner à merveille en faisant:

  Assert.AreEqual(expected.Count, actual.Intersect(expected).Count) 

Cependant, maintenant que j'ai un test qui doit être sensible à la casse, il se casse. J'ai essayé d'envoyer le second paramètre d'Intersect, StringComparer.Ordinal, StringComparer.InvariantCulture, et StringComparer.CurrentCulture ... pas de chance ..

Quelqu'un l'a déjà ressenti?

merci!

EDIT: voici les données:

Actual: 
    (0) "FOO" String 
    (1) "foo" String 
    (2) "Foo" String 
    (3) "fOo" String 
    (4) "foO" String 
    (5) "BAR" String 
    (6) "BAR" String 
    (7) "BAZ" String 
    (8) "baz" String 
    (9) "foo" String 

Expected: 

    (0) "FOO" String 
    (1) "foo" String 
    (2) "Foo" String 
    (3) "fOo" String 
    (4) "foO" String 
    (5) "BAR" String 
    (6) "BAR" String 
    (7) "BAZ" String 
    (8) "baz" String 
    (9) "foo" String 

actual.Intersect(expected, StringComparer.CurrentCulture) 

    (0) "FOO" String 
    (1) "foo" String 
    (2) "Foo" String 
    (3) "fOo" String 
    (4) "foO" String 
    (5) "BAR" String 
    (6) "BAZ" String 
    (7) "baz" String 

Il semble enlever une correspondance en double 'foo', et un double correspondant 'baz'. Peut-être existe-t-il une meilleure façon d'affirmer que les collections correspondent?

_EDIT2: Je pense que Intersect() supprime les doublons, ce qui explique pourquoi cela se brise. J'ai trouvé la classe CollectionAssert. C'est exactement ce dont j'avais besoin! Merci! _

+0

Quand vous dites « ça casse » et « pas de chance », que voulez-vous dire? Voulez-vous dire "ça casse" comme dans "ça donne le mauvais compte"? Voulez-vous dire "pas de chance" comme dans "cela donne le même mauvais résultat"? –

+0

Aussi, êtes-vous certain que le cas insensible à la casse fonctionne correctement, et ne donne pas simplement le nombre correct par coïncidence? –

+1

Et aussi, vous pouvez jeter un oeil à la classe CollectionAssert, qui peut être plus appropriée pour ce que vous essayez de faire. –

Répondre

2

Pour des fins de test utilisent CollectionAssert.AreEqual(actual, expected)

Vous recherchez SequenceEqual, pas Intersect. Intersect renvoie l'intersection de deux séquences, ie. les éléments partagés entre eux. L'utilisation d'Intersect sur {1, 2, 3} et {3, 4, 5} renvoie 3. SequenceEqual renvoie false.

vous ne trouviez pas CollectionAssert vous auriez pu utiliser:

Assert.IsTrue(actual.SequenceEqual(expected)) 
+1

Merci pour la réponse. J'ai regardé le document MSDN que vous avez posté ... une chose à noter, SequenceEqual semble comparer les références ... pas les valeurs réelles ... donc je pense que SequenceEqual aurait encore échoué sans implémenter IComparable. Toujours bon à savoir cependant! merci encore – dferraro

+0

@dferraro np ... vous pouvez l'utiliser directement et le comparateur d'égalité par défaut est utilisé pour les valeurs du type donné. Pour une classe personnalisée, il faudrait un 'IEqualityComparer' pour déterminer comment comparer les objets. –

1

Mettre en oeuvre un IEqualityComparer comme ceci:

Class StringCaseInsensitiveComparer
    Implements IEqualityComparer(Of String)
    Public Function Equals(ByVal s1 As String, ByVal s2 As String) As Boolean
        Return s1.ToLower() = s2.ToLower()
    End Function
    Public Function GetHashCode(ByVal s As String) As Integer
        Return s.GetHashCode()
    End Function
End Class

Ensuite, appelez cette surcharge de Intersection:

Dim first As IEnumerable(Of TSource)
Dim second As IEnumerable(Of TSource)
Dim comparer As IEqualityComparer(Of TSource)
Dim returnValue As IEnumerable(Of TSource)

faisant passer une instance du comparateur que vous venez de faire.

+0

Merci - J'ai compris que je devrais utiliser CollectionAssert. Mais revenons au problème original: les comparateurs InvariantCulture et CurrentCulture ne devraient-ils pas faire exactement ce que vous faites ici? Ils disent dans leur documentation 'fait une comparaison sensible à la casse' .. – dferraro

+0

Désolé, essayez plutôt d'utiliser StringComparer.InvariantCultureIgnoreCase, StringComparer.OrdinalIgnoreCase ou StringComparer.CurrentCultureIgnoreCase. –

+0

J'ai réalisé que le problème ne concerne pas la sensibilité à la casse - si vous regardez les données ci-dessus, il semble que intersect() filtre les doublons. C'est le problème – dferraro

Questions connexes