Ed Pavlov
Ed Pavlov

Reputation: 2508

How to assert that collection contains only one element with given property value?

How do I assert that collection contains only one element with given property value?

For example:

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

Upvotes: 15

Views: 15559

Answers (3)

BornToCode
BornToCode

Reputation: 10213

FluentAssertions has a method ContainSingle (on GenericCollectionAssertions class) and you can call it like myCollection.Should().ContainSingle();

Upvotes: 0

Dariusz Woźniak
Dariusz Woźniak

Reputation: 10350

1: You can use Has.Exactly() constraint:

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

But note since Property is get by reflection, you will get runtime error in case property "Name" will not exist.

2: (Recommended) However, it would be better to get property by a predicate rather than a string. In case property name will not exist, you will get a compile error:

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

3: Alternatively, you can rely on Count method:

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

Upvotes: 20

abatishchev
abatishchev

Reputation: 100238

Why don't use a bit of LINQ?

Assert.IsTrue(array.Single().Property("Name").EqualTo("1")); // Single() will throw exception if more then one

or

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

Upvotes: 1

Related Questions