Как сравнить списки в модульном тестировании

181

Как этот тест может провалиться?

[TestMethod]
public void Get_Code()
{
    var expected = new List<int>();
    expected.AddRange(new [] { 100, 400, 200, 900, 2300, 1900 });

    var actual = new List<int>();
    actual.AddRange(new [] { 100, 400, 200, 900, 2300, 1900 });

    Assert.AreEqual(expected, actual);
    // Assert.AreSame(expected, actual)       fails
    // Assert.IsTrue(expected.Equals(actual)) fails
}
Рэй Ченг
источник

Ответы:

371

Чтобы сделать утверждения о коллекциях, вы должны использовать CollectionAssert:

CollectionAssert.AreEqual(expected, actual);

List<T>не переопределяет Equals, поэтому, если Assert.AreEqualпросто позвонить Equals, он в конечном итоге будет использовать равенство ссылок.

Джон Скит
источник
6
Я хотел бы, чтобы это дало более подробные сообщения, когда это не удалось. «Разное количество элементов» и «Элемент с индексом 0 не совпадают» немного бесполезны. Что они тогда ?!
полковник Паник
32
Если вас не заботит порядок элементов: {A, B, C} == {C, B, A}, используйте CollectionAssert.AreEquivalentвместо этого msdn.microsoft.com/en-us/library/ms243779.aspx
user2023861
2
Обратите внимание, что это CollectionAssert.AreEqualможет быть заметно медленнее, чемAssert.IsTrue...SequenceEqual
Марк Соул
1
@MarkSowul: Но это дает гораздо лучшую диагностику отказов, верно?
Джон Скит
2
@MarkSowul: Хм ... звучит так, как будто стоит сообщить об ошибке. Нет причин, это должно быть так плохо.
Джон Скит
34

Я думаю, это поможет

Assert.IsTrue(expected.SequenceEqual(actual));
Shyju
источник
4
Это был и мой запасной вариант, но я надеюсь, что CollectionAssert предоставит более полезные сообщения об ошибках.
Джон Скит
4
К сожалению, на самом деле это не так: «CollectionAssert.AreEqual не удалось. (Элемент с индексом 0 не совпадает.)» (Что это за элементы?)
имя
17

Если вы хотите проверить, что каждый из них содержит одну и ту же коллекцию значений, вы должны использовать:

CollectionAssert.AreEquivalent(expected, actual);

Редактировать:

«Две коллекции эквивалентны, если они имеют одинаковые элементы в одинаковом количестве, но в любом порядке. Элементы равны, если их значения равны, а не если они ссылаются на один и тот же объект». - https://msdn.microsoft.com/en-us/library/ms243779.aspx

topham101
источник
14

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

Вызов метода:

CompareIEnumerable(to, emailDeserialized.ToIndividual,
            (x, y) => x.ToName == y.ToName && x.ToEmailAddress == y.ToEmailAddress);

Метод для сравнения:

private static void CompareIEnumerable<T>(IEnumerable<T> one, IEnumerable<T> two, Func<T, T, bool> comparisonFunction)
    {
        var oneArray = one as T[] ?? one.ToArray();
        var twoArray = two as T[] ?? two.ToArray();

        if (oneArray.Length != twoArray.Length)
        {
            Assert.Fail("Collections are not same length");
        }

        for (int i = 0; i < oneArray.Length; i++)
        {
            var isEqual = comparisonFunction(oneArray[i], twoArray[i]);
            Assert.IsTrue(isEqual);
        }
    }
Деклан
источник
3
Хорошее дополнение, или вы также можете переопределить Equalsметод, и CollectionAssertбудет работать.
Рэй Ченг
6

этот тест сравнивает ввод даты, проверяет, является ли ее високосным годом, если да, выводит 20 високосных лет от введенной даты, если нет, выводит СЛЕДУЮЩИЕ 20 високосных лет, myTest.Testing ссылается на экземпляр myTest, который, в свою очередь, вызывает значения из списка под названием «Тестирование», содержащего необходимые расчетные значения. часть упражнения, которую я должен был сделать.

[TestMethod]
        public void TestMethod1()
        {
            int testVal = 2012;
            TestClass myTest = new TestClass();
            var expected = new List<int>();
            expected.Add(2012);
            expected.Add(2016);
            expected.Add(2020);
            expected.Add(2024);
            expected.Add(2028);
            expected.Add(2032);
            expected.Add(2036);
            expected.Add(2040);
            expected.Add(2044);
            expected.Add(2048);
            expected.Add(2052);
            expected.Add(2056);
            expected.Add(2060);
            expected.Add(2064);
            expected.Add(2068);
            expected.Add(2072);
            expected.Add(2076);
            expected.Add(2080);
            expected.Add(2084);
            expected.Add(2088);
            var actual = myTest.Testing(2012);
            CollectionAssert.AreEqual(expected, actual);
        }
gettingThereSlowly
источник
0
List<AdminUser> adminDetailsExpected = new List<AdminUser>()
{
new AdminUser  {firstName = "test1" , lastName = "test1" , userId = 
"001test1"  },
new AdminUser {firstName = "test2" , lastName = "test2" , userId = 
"002test2"   }
};

// Закон

List<AdminUser> adminDetailsActual = RetrieveAdmin(); // your retrieve logic goes here

// Утверждай

Assert.AreEqual(adminDetailsExpected.Count, adminDetailsActual.Count);  //Test succeeds if the count matches else fails. This count can be used as a work around to test
Картик Касубха
источник
0

Беглые утверждения делают глубокие сравнения массивов actualArray.Should().BeEquivalentTo(expectedArray)

Рам Пратап
источник