Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Testing if a collection contains objects based on a particular property

I'm using NUnit 2.5.7. I want to test whether a collection of custom objects of a particular class contains certain objects, based on one of the class's properties.

e.g. a contrived example...

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); } 

Although it would be simple enough in this example, I don't want to create mock objects for each Person and use those in the assertion... I just want to check based on a particular property (Name in this example.)

like image 938
ngm Avatar asked Feb 23 '11 10:02

ngm


2 Answers

You can use Assert.That in conjunction with Has.Exactly(1).Matches:

List<Person> people = GetFavouritePeople() Assert.That(people, Has.Exactly(1).Matches<Person>(p => p.Name == "NUnit is amazing"))); 

Failure message will be along lines of:

Expected: exactly one item value matching lambda expression
But was: 0 items < [result of people.ToString()] >

like image 44
RJFalconer Avatar answered Oct 05 '22 18:10

RJFalconer


You could use LINQ:

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

or, if you want to be explicit about there being exactly one person with each name:

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

If you want a better error message than "Assertion failed, expected true, was false", you could create your own assert method.

For several collection-related asserts, CollectionAssert is very useful - for instance, it allows you to check if two collections contain the same elements, irrespective of their order. So yet another possibility is:

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

Note that CollectionAssert.AreEquivalent() is a little picky with regard to the types it accepts (even though the signature takes IEnumerable). I usually wrap it in another method that calls ToList() on both parameters before invoking CollectionAssert.AreEquivalent().

like image 195
Aasmund Eldhuset Avatar answered Oct 05 '22 17:10

Aasmund Eldhuset