Тестирование, если коллекция содержит объекты, основанные на определенном свойстве - PullRequest
15 голосов
/ 23 февраля 2011

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

например, надуманный пример ...

public class Person
{
    public string Name { get; set; }

    public Person(string name)
    {
        Name = name;
    }
}

// ...

public List<Person> GetFavouritePeople()
{
   List<Person> favouritePeople = new List<Person>();
   favouritePeople.Add(new Person("joe"));
   favouritePeople.Add(new Person("fred"));
   favouritePeople.Add(new Person("jenny"));

   return favouritePeople;
}

// ... 

[Test]
public GetFavouritePeople()
{
    List<Person> people = GetFavouritePeople();

    // What I'd like to test, but not sure how to do it...
    Assert.Contains(Name="joe", people);
    Assert.Contains(Name="fred", people);
    Assert.Contains(Name="jenny", people);
}

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

Ответы [ 2 ]

24 голосов
/ 23 февраля 2011

Вы можете использовать LINQ:

Assert.That(people.Any(p => p.Name == "joe"));

или, если вы хотите прямо указать, что с каждым именем ровно один человек:

Assert.That(people.Count(p => p.Name == "joe"), Is.EqualTo(1));

Если вам нужно более качественное сообщение об ошибке, чем «Утверждение не выполнено, ожидалось, что истина - ложь», вы можете создать свой собственный метод подтверждения.

Для нескольких утверждений, связанных с коллекциями, CollectionAssert очень полезен - например, он позволяет проверить, содержат ли две коллекции одинаковые элементы независимо от их порядка. Итак, еще одна возможность:

CollectionAssert.AreEquivalent(new[] {"joe", "fred", "jenny"}, people.Select(p => p.Name).ToList());

Обратите внимание, что CollectionAssert.AreEquivalent() немного требователен к типам, которые он принимает (даже если подпись принимает IEnumerable). Я обычно заключаю его в другой метод, который вызывает ToList() для обоих параметров перед вызовом CollectionAssert.AreEquivalent().

0 голосов
/ 06 октября 2017

Вы можете использовать Linq's Intersect(), чтобы определить, находятся ли все ожидаемые элементы в списке, с которым вы тестируете, даже если список содержит другие элементы, для которых вы не тестируете:

[Test]
public void TestFavouritePeople()
{
    var people = GetFavouritePeople();
    var names = people.Select(p => p.Name);

    var expectedNames = new[] {"joe", "fred", "jenny"};
    var actualNames = names.Intersect(expectedNames);

    CollectionAssert.AreEquivalent(expectedNames, actualNames);
}

Для NUnit 3.0 и выше вы можете использовать Is.SupersetOf():

[Test]
public void TestFavouritePeople()
{
    var people = GetFavouritePeople();
    var names = people.Select(p => p.Name);

    var expectedNames = new[] {"joe", "fred", "jienny"};
    var actualNames = names;

    Assert.That(actualNames, Is.SupersetOf(expectedNames)); 
}
...