测试集合是否包含基于特定属性的对象

ngm*_*ngm 16 c# collections nunit unit-testing nunit-2.5

我正在使用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);
}
Run Code Online (Sandbox Code Playgroud)

虽然在这个例子中它很简单,但我不想为每个Person创建模拟对象并在断言中使用它们......我只想根据特定属性(本例中的Name)进行检查.

Aas*_*set 27

您可以使用LINQ:

Assert.That(people.Any(p => p.Name == "joe"));
Run Code Online (Sandbox Code Playgroud)

或者,如果你想明确指出每个名字只有一个人:

Assert.That(people.Count(p => p.Name == "joe"), Is.EqualTo(1));
Run Code Online (Sandbox Code Playgroud)

如果您想要一个比"断言失败,预期为真,是假"更好的错误消息,您可以创建自己的断言方法.

对于几个与集合相关的断言,CollectionAssert非常有用 - 例如,它允许您检查两个集合是否包含相同的元素,而不管它们的顺序如何.所以另一种可能性是:

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

请注意,CollectionAssert.AreEquivalent()对于它接受的类型(即使签名需要IEnumerable),它有点挑剔.我通常将它包装在另一个ToList()在调用之前调用这两个参数的方法中CollectionAssert.AreEquivalent().


RJF*_*ner 7

您可以Assert.That结合使用Has.Exactly(1).Matches

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

失败消息将沿着以下几行:

预期:正好与 lambda 表达式匹配的一项值
但是是:0 项 < [people.ToString() 的结果] >