Проверка, содержит ли коллекция объекты на основе определенного свойства

Я использую 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 ответов


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

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

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

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

если вы хотите лучшее сообщение об ошибке, чем "утверждение не удалось, ожидалось true, было false", вы можете создать свой собственный метод assert.

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

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

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


вы можете использовать LINQ-это 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)); 
}