Question

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.)

Was it helpful?

Solution

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().

OTHER TIPS

You can use Linq's Intersect() to determine whether all the expected items are within the list your testing against even if the list contains other items that you are not testing for:

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

For NUnit 3.0 and greater, you can use 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)); 
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top