рекурсивное утверждение на коллекции - PullRequest
4 голосов
/ 15 ноября 2010

Я бы хотел такой тест:

[Test]
    public void TestCollectionAssert ()
    {
        var a1 = new [] { new [] { "a" } };
        var a2 = new [] { new [] { "a" } };

        Assert.AreNotEqual (a1, a2);
        //CollectionAssert.AreEqual (a1, a2);
        CollectionAssert.AreEquivalent (a1, a2);
    }

пройти. Мой реальный случай более сложный, но решение этого общего вопроса подойдет. Есть идеи?

Ответы [ 3 ]

2 голосов
/ 15 ноября 2010

Есть полезный оператор LINQ, называемый SequenceEqual(), который сравнивает две последовательности на равенство. SequenceEqual() просматривает любые две последовательности IEnumerable<> и проверяет, имеют ли они одинаковое число элементов и что элементы с одинаковым индексом равны (с помощью сравнения по умолчанию равенство). Однако, поскольку у вас есть вложенные коллекции, вам необходимо расширить концепцию равенства, чтобы применить их и к ним. К счастью, существует перегрузка, которая позволяет вам предоставить свой собственный объект IEqualityComparer<>.

Поскольку неудобно постоянно определять класс для обеспечения семантики равенства, я написал общее расширение, которое позволяет вам вместо этого использовать делегат. Давайте посмотрим на код:

public static class ComparerExt
{
    private class GenericComparer<T> : IEqualityComparer<T>
    {
        private readonly Func<T, T, bool> m_EqualityFunc;

        public GenericComparer( Func<T,T,bool> compareFunc )
        {
            m_EqualityFunc = compareFunc;
        }

        public bool Equals(T x, T y)
        {
            return m_EqualityFunc(x, y);
        }
    }

    // converts a delegate into an IComparer
    public static IEqualityComparer<T> AreEqual<T>( Func<T,T,bool> compareFunc )
    {
        compareFunc.ThrowIfNull("compareFunc");

        return new GenericComparer<T>(compareFunc);
    }
}

Теперь мы можем легко сравнить две последовательности:

Assert.IsTrue( 
   // check that outer sequences are equivalent...
   a1.SequenceEqual( a2,
                     // define equality as inner sequences being equal... 
                     ComparerExt.AreEqual( (a,b) => a.SequenceEqual(b) ) );
0 голосов
/ 23 ноября 2013

Это старый вопрос, но кто-то только что разместил ссылку в списке обсуждений nunit, поэтому я отвечу.

NUnit предназначен для сообщения двух списков как равных. Вот только как это работает. Фактически Assert.NotEqual должен завершиться ошибкой.

0 голосов
/ 15 ноября 2010

Вы можете написать метод расширения, подобный приведенному ниже.

public class AssertExtension
{
    public bool AreSimilar<T>(this CollectionAssert, IList<T> list1, IList<T> list2)
    {
        // ...
    }
}

Проблема, конечно, в том, как сравнить эти два списка. Я бы предложил пройтись по элементам одного списка и попытаться удалить их из другого. Если при выполнении этого возникнет проблема или в конце останутся объекты, они не похожи.

...