What's the most idiomatic way with NUnit 2.6 to assert that two collections are of equal length regardless of their elements' values?
I can see several ways of expressing that assertion. Which one is preferred, or are there disadvantages/advantages with using one or the other?
Assert.That(coll1, Has.Count.EqualTo(coll2.Count));
Assert.That(coll1.Count, Is.EqualTo(coll2.Count));
Assert.AreEqual(coll1.Count, coll2.Count);
I can see that the first option provides a nice output in case the assertion failed (Expected count of ... but actually got ...), whereas the other two options only output "Expected ..., actual ..." unless I provide a custom message through an additional parameter.
I prefer:
Assert.That(collection, Has.Count.EqualTo(expectedCount));
Simply because .Count
and Count()
could be incorrectly overridden (which should be tested in a different unit test if they are, although I don't know how nunit is actually doing the count internally). Bascially I don't want my actual to have any side affect logic. Calling Count
or Count()
should probably be done in the act like:
// Arrange
var expectedCount = 8;
// Act
var list = GetList();
var actualCount = list.Count();
// Assert
Assert.That(actualCount, Is.EqualTo(expectedCount));
Both read fairly the same, but the first one has less logic to look over when it fails.
Update: dec-1-2020
Considering the number of upvotes this has received, I think I should mention that using https://fluentassertions.com/ (FA) is advantageous. This could be written in the following ways and reads much nicer:
// Arrange
// Act
var list = GetList();
// Assert
list.Should().BeEmpty();
or
// Arrange
// Act
var list = GetList();
// Assert
list.Should().HaveCount(8);
or
// Arrange
// Act
var list = GetList();
// Assert
list.Should().HaveCountLessThanOrEqualTo(10);
Beyond the OP question, FA can do some very advanced collection rules:
// Arrange
// Act
var persons = GetPersons();
// Assert
persons.Should().BeInAscendingOrder(p => p.LastName)
.And().OnlyHaveUniqueItems(p => p.id);
The framework goes way beyond collections and adds readability to testing other topics as well.
// Arrange
// Act
Action action = () => 8 / 0;
//
action.Should().Throw<DivideByZeroException>();
I have no association with fluent assertions.
I think it's personal preference really but for I go for:
Assert.That(coll1.Count(), Is.EqualTo(coll2.Count()));
Using linq and if the underlying collection/Enumerable type changed it would still work in most cases, you not testing the type just the count. This also works for things that don't have .Count
on them like IDBSet
for example. But then again I don't see anything wrong with .AreEqual
either. If the next engineer understands then it's a winner, eh?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With