Нанит сравнение двух списков
Итак, я довольно новичок в модульном тестировании, и до сих пор все идет хорошо. Я упрощаю свою задачу здесь, но в основном у меня есть следующее:
[Test]
public void ListTest()
{
var expected = new List<MyClass>();
expected.Add(new MyOtherClass());
var actual = new List<MyClass>();
actual.Add(new MyOtherClass());
Assert.AreEqual(expected,actual);
//CollectionAssert.AreEqual(expected,actual);
}
Но тест провален,разве тест не должен пройти? чего мне не хватает?
6 ответов:
Я преобразую свой комментарий в ответ на запрос.
Ну, это не удается, потому что
AreEqual
использует сравнение ссылок. Чтобы заставить его работать, вам нужно сравнение значений (ваше собственное пользовательское сравнение).Вы можете в значительной степени сделать это, реализовав IEquatable интерфейс. и имейте в виду, когда вы реализуете этот интерфейс, вы должны переопределить
Object.Equals
иObject.GetHashCode
, чтобы получить последовательные результаты..Net framework поддерживает это без реализации
IEquatable
вам нужен IEqualityComparer, который должен сделать трюк, ноnunit
должен иметь метод, который принимает это как перегрузку. Хотя насчет "нунит" я не уверен.
Если вы сравниваете два списка, вы должны использовать тест с использованием ограничений коллекции.
Assert.That(actual, Is.EquivalentTo(expected));
Кроме того, в ваших классах вам нужно будет переопределить метод Equals, в противном случае, как заявил гленг, элементы в списке все равно будут сравниваться на основе ссылки.
Простой пример переопределения:
public class Example { public int ID { get; set; } public override bool Equals(object obj) { return this.ID == (obj as Example).ID; } }
Очень простой способ заставить этот тест работать - создать экземпляр
MyOtherClass
только один раз. Таким образом, при сравнении элементов в двух списках они будут "равны" (поскольку ссылаются на один и тот же объект). Если вы сделаете это,CollectionAssert
будет работать просто отлично.[Test] public void ListTest() { var thing = new MyOtherClass(); var expected = new List<MyClass>(); expected.Add(thing); var actual = new List<MyClass>(); actual.Add(thing); CollectionAssert.AreEqual(expected,actual); }
Если вы этого не сделаете, вам нужно будет реализовать
IEquatable<MyOtherClass>
вMyOtherClass
или переопределитьEquals
, чтобы определить, что делает два экземпляра этого класса "одинаковыми".
Постарайтесь быть немного более конкретным в том, чего вы пытаетесь достичь. Явное указание на то, что вы хотите сравнить всю последовательность, решит проблему. Я лично не стал бы полагаться на причудливые особенности NUnit для определения того, что вы имели в виду, говоря, что они равны. Например,
Assert.IsTrue(actual.SequenceEqual(expected));
Из Nunit документация:
Начиная с версии 2.2, специальное положение также предусмотрено для сравнения одномерных массивов. Два массива будут рассматриваться Assert как равные.Равны, если они одинаковой длины и каждый из соответствующих элементов равен. Примечание: многомерные массивы, вложенные массивы (массивы массивов) и другие типы коллекций, такие как ArrayList, в настоящее время не поддерживаются.
У вас есть список объектов ... так что дело не в этом. то же самое, что сравнивать 2 Инта. То, что вы должны сделать, это, вероятно, сравнить все объекты в списке ... (Попробуйте преобразовать список в массив ... может действительно сработать :))
Как я уже сказал (и большинство других), вам, вероятно, потребуется переопределить Equals. Вот страницаMSDN о том, как это сделать (охватывает Equals, = = operator и GetHashCode).
Аналогично с дополнительной информацией : [сравните-равенства-между-двумя-предметы-в-нанит]
(сравните равенство между двумя объектами в NUnit )
Если вы не можете изменить класс, то этот пример может быть полезен:
[Test] public void Arrays_Should_Be_Equal() { MyClass[] array1 = GetTestArrayOfSize(10); MyClass[] array2 = GetTestArrayOfSize(10); // DOESN'T PASS // Assert.That(array1, Is.EquivalentTo(array2)); Func<MyClass, object> selector = i => new { i.Property1, i.Property2 }; Assert.That(array1.Select(selector), Is.EquivalentTo(array2.Select(selector))); } private MyClass[] GetTestArrayOfSize(int count) { return Enumerable.Range(1, count) .Select(i => new MyClass { Property1 = "Property1" + i, Property2 = "Property2" + i }).ToArray(); }