如何断言集合仅包含一个具有给定属性值的元素?

15

如何断言集合中只包含一个具有给定属性值的元素?

例如:

class Node
{
  private readonly string myName;
  public Node(string name)
  {
    myName = name;
  }
  public string Name { get; set; }
}

[Test]
public void Test()
{
  var array = new[]{ new Node("1"), new Node("2"), new Node("1")};
  Assert.That(array, Has.Some.Property("Name").EqualTo("1"));
  Assert.That(array, Has.None.Property("Name").EqualTo("1"));

  // and how to assert that node with Name="1" is single?
  Assert.That(array, Has.???Single???.Property("Name").EqualTo("1"));
}
3个回答

19

1:您可以使用 Has.Exactly() 约束条件:

Assert.That(array, Has.Exactly(1).Property("Name").EqualTo("1"));

请注意,由于属性是通过反射获取的,如果属性的名称“Name”不存在,您将会在运行时出现错误。

2: (建议) 然而,最好通过谓词而不是字符串来获取属性。如果属性名称不存在,您将会得到一个编译错误:

Assert.That(array, Has.Exactly(1).Matches<Node>(x => x.Name == "1"));    

3:或者您可以依赖于 Count 方法:

Assert.That(array.Count(x => x.Name == "1"), Is.EqualTo(1));

1
为什么不使用一点LINQ呢?
Assert.IsTrue(array.Single().Property("Name").EqualTo("1")); // Single() will throw exception if more then one

或者

Assert.IsTrue(array.Count(x => x.Property("Name").EqualTo("1") == 1); // will not

为什么不完全使用LINQ代替NUnit断言呢? Assert.IsTrue(array.Where(x => x.Property("Name") == 1 ).Any()); Assert.IsFalse(array.Where(x => x.Property("Name") == 1 ).Any()); ;) - Ed Pavlov
1
因为一次性断言信息第一次出现问题时不易读取:您将收到一个“它是真的,但它是假的”消息,而不是更容易理解的消息。 - Giulio Caccin

0
FluentAssertions有一个方法叫做ContainSingle(在GenericCollectionAssertions类中),你可以像这样调用它: myCollection.Should().ContainSingle();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接