2010-03-14 9 views
32

Parece que CollectionAssert no se puede usar con genéricos. Esto es súper frustrante; el código que quiero probar usa genéricos. ¿Qué voy a hacer? Escribir un texto estándar para convertir entre los dos? ¿Verifica manualmente la equivalencia de cobro?Colección ¿Uso de postres con genéricos?

Esta falla:

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)); 

errores del compilador:

de error 1:

'System.Collections.Generic.IEnumerator>' no contiene una definición para 'ToList' y no se pudo encontrar ningún método de extensión 'ToList' que aceptara un primer argumento de tipo 'System.Collections.Generic.IEnumerator>'

Error 2

'System.Collections.Generic.IEnumerator>' no contiene una definición para 'ToList' y ningún método de extensión 'ToList' aceptar un primer argumento de tipo 'System.Collections.Generic. IEnumerator>' se pudo encontrar

Error 3

'System.Collections.Generic.IEnumerator>' no contiene una definición para '' SequenceEquals y ningún método de extensión 'SequenceEquals' aceptar un primer argumento de escriba 'System.Collections.Generic.IEnumerator>' se puede encontrar

¿Qué estoy haciendo mal? ¿No estoy usando extensiones correctamente?

Actualización: Ok, esto se ve un poco mejor, pero todavía no funciona:

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

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

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

no quiero ser la comparación de las listas; Solo me importa establecer igualdad de membresía. El orden de los miembros no es importante. ¿Cómo puedo evitar esto?

+0

¿Estás seguro? Me ha estado dando errores de compilación, que publicaré mañana por la mañana. –

+0

Estaba equivocado; CollectionAssert NO funcionará en un ICollection . Funciona solo con ICollection. Esto se solicitó en Connect, pero hasta ahora no se implementó. Posible solución: http://stackoverflow.com/questions/662458/unittesting-ilist-with-collectionassert –

+0

Si no recuerdo mal, las interfaces ICollection e ICollection son MUY diferentes. Este no es el caso de IEnumerable versus IEnumerable . Por favor revisa sus métodos. ICollection se usa para algo diferente de ICollection . ICollection ni siquiera tiene el método ADD, se usa para propósitos de "más bajo nivel" como multithreading y clasificación. Por lo tanto, creo que debería encontrar una interfaz que se adapte mejor a sus necesidades, ¿simple IEnumerable tal vez? – quetzalcoatl

Respuesta

1

Puede escribir fácilmente su propia versión genérica, luego moverla a una base o clase de utilidad que se utiliza en todas sus pruebas. Base en los operadores LINQ como All y Any.

33

Usted puede use CollectionAssert con las colecciones genéricas. El truco consiste en comprender que los métodos CollectionAssert operan en ICollection, y aunque pocas interfaces de colección genéricas implementan ICollection, List<T> sí lo hace.

Por lo tanto, se puede superar esta limitación mediante el uso del método ToList extensión:

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

Dicho esto, sigo considerando CollectionAssert roto en un montón de otras maneras, por lo que tienden a usar Assert.IsTrue con los métodos de extensión de LINQ, así:

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

Fwiw, actualmente estoy usando estos métodos de extensión para realizar otras comparaciones:

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; 
    } 
} 
+0

Esto me da errores de compilación (ver arriba). –

+1

Tiene que importar el espacio de nombres System.Linq en una directiva using. 'ToList' es un método de extensión. –

+0

Agregué 'using System.Linq;' pero aún no funciona: \t ''System.Collections.Generic.IEnumerator >' no contiene una definición para ' ToList 'y ningún método de extensión' ToList 'que acepte un primer argumento de tipo' System.Collections.Generic.IEnumerator > 'podría encontrarse' –

5

Si está trabajando con conjuntos, a continuación, use esta Idiom

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

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