This is the second of my posts on the brilliant FluentAssertions library. You can find the rest of the posts here:

OK, so today we’ll jump right into the various assertions we can make on dates, times and collections.

Dates and Times

This is where the wonder of FluentAssertions really starts to shine through, DateTime assertions become hugely more readable. Take the simplest example:

Assert.AreEqual(DateTime.Parse("08/10/2008"), myDateValue);

Urgh. This does not read at all well, to start with I’m in the UK but I’m sure a lot of you guys over the pond read that as 10th August. (I know, it could have been written a little better, I’m labouring the point OK?) Let’s try it again:

myDateValue.Should().Be(8.October(2008));

Great, it reads better, and there is no chance of confusion over our intention. How about this:

myDateValue.Should().BeWithin(5.Days()).After(10.January(2010));
I really don’t need to explain what we are asking above which is absolutely brilliant. You can call your product owner over to query how some feature should work, and they can see that you are asking the correct questions – without having to know how to write a single line of c# code.

You can chain your expectations using the And keyword just as you could for strings as well:

myDateValue.Should().BeWithin(5.Days()).After(10.January(2010))
  .And.BeAtLeast(6.Hours()).Before(15.January(2010).At(21, 00));

It’s worth playing around with code completion, but some of the DateTime methods available include: BeBefore, BeAfter, BeWithin, HaveDay/Month/Year/Hour/Minute/Second, BeAtLeast, BeMoreThan.

Collections

Next up there are a few really nice collection assertions. Let’s say you want to ensure that a collection is empty. In MsTest you would write:

Assert.AreEqual(0, items.Count);

You could obviously improve this to:

items.Count.Should().Be(0);

But you can actually write this instead:

items.Should().BeEmpty();

Once again, the language of your assertions is very similar to the natural language used to define acceptance criteria.

Collections is where I find myself chaining assertions the most. You could write something similar to:

items.Should().HaveCount(5)
  .And.NotContainNulls()
  .And.OnlyHaveUniqueItems()
  .And.NotContain(15);

There are a multitude of assertions available for inspecting the contents of your collection. This example wouldn’t work but will show you some the various methods available to you:

items.Should().Contain(new[] {1, 2, 3})
  .And.ContainInOrder(new[] {7, 10})
  .And.HaveSameCount(someOtherCollection)
  .And.NotBeSubsetOf(someOtherCollection)
  .And.ContainItemsAssignableTo<int>();

You can even use predicates:

items.Should().OnlyContain(n => n > 3)
  .And.Contain(n => n > 40);

So the collection should only contain numbers larger than three, and at least one item larger than 40. This isn’t as readable however so I generally tend to create my own custom assertions in these cases, which I’ll go through in part 4 of this series.

So, that’s all you need to know about basic FluentAssertions. I’ll admit to finding this series tricky to write so far as all the code examples are so obvious, but next time we’ll dig into some of the more in depth stuff you can do with exception and event assertions. I’ll finish up in part 4 by describing how you can create your own assertions library to keep your tests clean and readable. Thanks for reading!