Skip to main content

Collections

Describes the possible expectations for collections.

Equality

You can verify, that a collection matches another collection:

IEnumerable<int> values = Enumerable.Range(1, 3);

await Expect.That(values).IsEqualTo([1, 2, 3]);
await Expect.That(values).IsEqualTo([3, 2, 1]).InAnyOrder();
await Expect.That(values).IsEqualTo([1, 1, 2, 2, 3, 3]).IgnoringDuplicates();
await Expect.That(values).IsEqualTo([3, 3, 2, 2, 1, 1]).InAnyOrder().IgnoringDuplicates();

Note: The same expectation works also for IAsyncEnumerable<T>.

Has count

You can verify the number of items in a collection:

IEnumerable<int> values = Enumerable.Range(1, 10);

await Expect.That(values).HasCount(10);
// or more explicit
await Expect.That(values).HasCount().EqualTo(10);

await Expect.That(values).HasCount().AtLeast(9);
await Expect.That(values).HasCount().AtMost(11);
await Expect.That(values).HasCount().Between(8).And(12);

All be

You can verify, that all items in the collection are equal to the expected value

await Expect.That([1, 1, 1]).All().AreEqualTo(1);

You can also use a custom comparer or configure equivalence:

IEnumerable<MyClass> values = //...
MyClass expected = //...

await Expect.That(values).All().AreEqualTo(expected).Equivalent();
await Expect.That(values).All().AreEqualTo(expected).Using(new MyClassComparer());

For strings, you can configure this expectation to ignore case, ignore newline style, ignoring leading or trailing white-space, or use a custom IEqualityComparer<string>:

await Expect.That(["foo", "FOO", "Foo"]).All().AreEqualTo("foo").IgnoringCase();

Note: The same expectation works also for IAsyncEnumerable<T>.

All be unique

You can verify, that all items in a collection are unique.

await Expect.That([1, 2, 3]).AreAllUnique();

Note: The same expectation works also for IAsyncEnumerable<T>.

For dictionaries, this expectation only verifies the values, as the keys are unique by design:

IDictionary<int, int> subject = new Dictionary<int, int>
{
{ 1, 1 },
{ 2, 1 }
};

// This following expectation will fail, even though the keys are unique!
await Expect.That(subject).AreAllUnique();

Elements

You can add expectations that a certain number of elements must meet.

Comply with

You can verify, that items in a collection comply with an expectation on the individual elements:

await Expect.That([1, 2, 3]).All().ComplyWith(item => item.IsLessThan(4));
await Expect.That([1, 2, 3]).AtLeast(2).ComplyWith(item => item.IsGreaterThanOrEqualTo(2));
await Expect.That([1, 2, 3]).AtMost(1).ComplyWith(item => item.IsNegative());
await Expect.That([1, 2, 3]).Between(2).And(3).ComplyWith(item => item.IsPositive());
await Expect.That([1, 2, 3]).Exactly(1).ComplyWith(item => item.IsEqualTo(2));
await Expect.That([1, 2, 3]).None().ComplyWith(item => item.IsNegative());

Note: The same expectation works also for IAsyncEnumerable<T>.

Satisfy

You can verify, that items in a collection satisfy a condition:

await Expect.That([1, 2, 3]).All().Satisfy(item => item < 4);
await Expect.That([1, 2, 3]).AtLeast(2).Satisfy(item => item >= 2);
await Expect.That([1, 2, 3]).AtMost(1).Satisfy(item => item < 0);
await Expect.That([1, 2, 3]).Between(2).And(3).Satisfy(item => item > 0);
await Expect.That([1, 2, 3]).Exactly(1).Satisfy(item => item == 2);
await Expect.That([1, 2, 3]).None().Satisfy(item => item < 0);

Note: The same expectation works also for IAsyncEnumerable<T>.

Sort order

You can verify, that the collection contains is sorted in ascending or descending order:

await Expect.That([1, 2, 3]).IsInAscendingOrder();
await Expect.That(["c", "b", "a"]).IsInDescendingOrder();

You can also specify a custom comparer:

await Expect.That(["a", "B", "c"]).IsInAscendingOrder().Using(StringComparer.OrdinalIgnoreCase);

For objects, you can also verify the sort order on a member:

MyClass[] values = //...

await Expect.That(values).IsInAscendingOrder(x => x.Value);

Note: The same expectation works also for IAsyncEnumerable<T>.

Contain

You can verify, that the collection contains a specific item or not:

IEnumerable<int> values = Enumerable.Range(1, 20);

await Expect.That(values).Contains(13);
await Expect.That(values).DoesNotContain(42);

You can also set occurrence constraints on Contain:

IEnumerable<int> values = [1, 1, 1, 2];

await Expect.That(values).Contains(1).AtLeast(2.Times());
await Expect.That(values).Contains(1).Exactly(3.Times());
await Expect.That(values).Contains(1).AtMost(4.Times());
await Expect.That(values).Contains(1).Between(1).And(5.Times());

You can also use a custom comparer or configure equivalence:

IEnumerable<MyClass> values = //...
MyClass expected = //...

await Expect.That(values).Contains(expected).Equivalent();
await Expect.That(values).Contains(expected).Using(new MyClassComparer());

Note: The same expectation works also for IAsyncEnumerable<T>.

Predicate

You can verify, that the collection contains an item that satisfies a condition:

IEnumerable<int> values = Enumerable.Range(1, 20);

await Expect.That(values).Contains(x => x > 12 && x < 14);
await Expect.That(values).DoesNotContain(x => x >= 42);

You can also set occurrence constraints on Contain:

IEnumerable<int> values = [1, 1, 1, 2];

await Expect.That(values).Contains(x => x == 1).AtLeast(2.Times());
await Expect.That(values).Contains(x => x == 1).Exactly(3.Times());
await Expect.That(values).Contains(x => x == 1).AtMost(4.Times());
await Expect.That(values).Contains(x => x == 1).Between(1).And(5.Times());

Note: The same expectation works also for IAsyncEnumerable<T>.

Contain subset

You can verify, that a collection contains another collection as a subset:

IEnumerable<int> values = Enumerable.Range(1, 3);

await Expect.That(values).Contains([1, 2]);
await Expect.That(values).Contains([3, 2]).InAnyOrder();
await Expect.That(values).Contains([1, 1, 2, 2]).IgnoringDuplicates();
await Expect.That(values).Contains([3, 3, 1, 1]).InAnyOrder().IgnoringDuplicates();

Note: The same expectation works also for IAsyncEnumerable<T>.

To check for a proper subset, append .Properly() (which would fail for equal collections).

Be contained in

You can verify, that a collection is contained in another collection (it is a superset):

IEnumerable<int> values = Enumerable.Range(1, 3);

await Expect.That(values).IsContainedIn([1, 2, 3, 4]);
await Expect.That(values).IsContainedIn([4, 3, 2, 1]).InAnyOrder();
await Expect.That(values).IsContainedIn([1, 1, 2, 2, 3, 3, 4, 4]).IgnoringDuplicates();
await Expect.That(values).IsContainedIn([4, 4, 3, 3, 2, 2, 1, 1]).InAnyOrder().IgnoringDuplicates();

Note: The same expectation works also for IAsyncEnumerable<T>.

To check for a proper superset, append .Properly() (which would fail for equal collections).

Start with

You can verify, if a collection starts with another collection or not:

IEnumerable<int> values = Enumerable.Range(1, 3);

await Expect.That(values).StartsWith(1, 2);
await Expect.That(values).DoesNotStartWith(2, 3);

You can also use a custom comparer or configure equivalence:

IEnumerable<MyClass> values = //...
MyClass expected = //...

await Expect.That(values).StartsWith(expected).Equivalent();
await Expect.That(values).StartsWith(expected).Using(new MyClassComparer());

For strings, you can configure this expectation to ignore case, ignore newline style, ignoring leading or trailing white-space, or use a custom IEqualityComparer<string>:

await Expect.That(["FOO", "BAR"]).StartsWith(["foo"]).IgnoringCase();

Note: The same expectation works also for IAsyncEnumerable<T>.

End with

You can verify, if a collection ends with another collection or not:

IEnumerable<int> values = Enumerable.Range(1, 5);

await Expect.That(values).EndsWith(4, 5);
await Expect.That(values).DoesNotEndWith(3, 5);

You can also use a custom comparer or configure equivalence:

IEnumerable<MyClass> values = //...
MyClass expected = //...

await Expect.That(values).EndsWith(expected).Equivalent();
await Expect.That(values).EndsWith(expected).Using(new MyClassComparer());

For strings, you can configure this expectation to ignore case, ignore newline style, ignoring leading or trailing white-space, or use a custom IEqualityComparer<string>:

await Expect.That(["FOO", "BAR"]).EndsWith(["bar"]).IgnoringCase();

Note: The same expectation works also for IAsyncEnumerable<T>.

Caution: this method will always have to completely materialize the enumerable!

Have

Specifications that count the elements in a collection.

All

You can verify, that all items in the collection, satisfy an expectation:

IEnumerable<int> values = Enumerable.Range(1, 20);

await Expect.That(values).All().Satisfy(i => i <= 20);

Note: The same expectation works also for IAsyncEnumerable<T>.

At least

You can verify, that at least minimum items in the collection, satisfy an expectation:

IEnumerable<int> values = Enumerable.Range(1, 20);

await Expect.That(values).AtLeast(9).Satisfy(i => i < 10);

Note: The same expectations works also for IAsyncEnumerable<T>.

At most

You can verify, that at most maximum items in the collection, satisfy an expectation:

IEnumerable<int> values = Enumerable.Range(1, 20);

await Expect.That(values).AtMost(1).Satisfy(i => i < 2);

Note: The same expectations works also for IAsyncEnumerable<T>.

Between

You can verify, that between minimum and maximum items in the collection, satisfy an expectation:

IEnumerable<int> values = Enumerable.Range(1, 20);

await Expect.That(values).Between(1).And(2).Satisfy(i => i < 2);

Note: The same expectations works also for IAsyncEnumerable<T>.

Exactly

You can verify, that exactly expected items in the collection, satisfy an expectation:

IEnumerable<int> values = Enumerable.Range(1, 20);

await Expect.That(values).Exactly(9).Satisfy(i => i < 10);

Note: The same expectations works also for IAsyncEnumerable<T>.

None

You can verify, that not item in the collection, satisfies an expectation:

IEnumerable<int> values = Enumerable.Range(1, 20);

await Expect.That(values).None().Satisfy(i => i > 20);

You can also verify, that the collection is empty.

IEnumerable<int> values = Array.Empty<int>();

await Expect.That(values).IsEmpty();

Note: The same expectations works also for IAsyncEnumerable<T>.

Have single

You can verify, that the collection contains a single element that satisfies an expectation.

IEnumerable<int> values = [42];

await Expect.That(values).HasSingle();
await Expect.That(values).HasSingle().Which.IsGreaterThan(41);

The awaited result is the single element:

IEnumerable<int> values = [42];

int result = await Expect.That(values).HasSingle();
await Expect.That(result).IsGreaterThan(41);

Note: The same expectation works also for IAsyncEnumerable<T>.

Dictionaries

Contain key(s)

You can verify, that a dictionary contains the expected key(s):

Dictionary<int, string> values = new() { { 42, "foo" }, { 43, "bar" } };

await Expect.That(values).ContainsKey(42);
await Expect.That(values).ContainsKeys(42, 43);
await Expect.That(values).DoesNotContainKey(44);
await Expect.That(values).DoesNotContainKeys(44, 45, 46);

You can add additional expectations on the corresponding value(s):

Dictionary<int, string> values = new() { { 42, "foo" }, { 43, "bar" }, { 44, "baz" } };

await Expect.That(values).ContainsKey(42).WhoseValue.IsEqualTo("foo");
await Expect.That(values).ContainsKeys(43, 44).WhoseValues.ComplyWith(v => v.StartsWith("ba"));

Contain value(s)

You can verify, that a dictionary contains the expected value(s):

Dictionary<int, string> values = new() { { 42, "foo" }, { 43, "bar" } };

await Expect.That(values).ContainsValue("foo");
await Expect.That(values).ContainsValues("foo", "bar");
await Expect.That(values).DoesNotContainValue("something");
await Expect.That(values).DoesNotContainValues("something", "else");