Pregunta ¿Uso de CollectionSsert con genéricos?


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?

Esto 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:

Error 1:

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

Error 2

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

Error 3

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

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

Actualizar: Ok, esto se ve un poco mejor, pero aún 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 comparar listas; Solo me importa establecer igualdad de membresía. El orden de los miembros no es importante. ¿Cómo puedo evitar esto?


32
2018-03-14 04:30


origen


Respuestas:


poder use CollectionAssert con colecciones genéricas. El truco consiste en comprender que los métodos CollectionAssert funcionan en ICollection, y aunque pocas interfaces genéricas de colección implementan ICollection, List<T> hace.

Así, puede evitar esta limitación utilizando el ToList método de extensión:

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

Dicho esto, todavía considero que CollectionAssert está roto en muchas otras formas, así que tiendo a usar Assert.IsTrue con los métodos de extensión 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;
    }
}

33
2018-03-14 07:06



Si está trabajando con Conjuntos, entonces use este Idioma

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

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

5
2018-05-20 09:32



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


1
2018-03-14 04:40