Application testing
.NET Core BDD C# Fluent Assertion NUnit Visual Studio

BDD Testing using Fluent Assertions and NUnit with .NET Core

Welcome to today’s post.

I will discuss how to create unit tests within a .NET Core test application using a BDD test utility.

I will show how to use the BDD third-party tool Fluent Assertions within Visual Studio.

In a previous post I showed how to create unit tests using the SpecFlow test utility.

Before I show how to implement unit tests in the Visual Studio development environment, I will explain what BDD testing is.

What is BDD?

BDD is the abbreviation for Behavioral Driven Testing.

BDD is a natural way to write unit tests for applications. It uses natural language syntax that makes the unit tests and assertions easier to implement by testers and less technical staff that are involved in the testing process.

It structures tests into features with scenarios. These are equivalent to test scripts.

This makes it easier for developers that integrate unit tests and BDD tests into applications to associate these tests with the test scripts that members of the test team create and ensure that each application build incorporates an equivalent BDD test that includes a test script.

In each scheduled development and test build, the results of test runs including tests that fail can be dispatched to the test team for evaluation. In addition, developers can view failed test runs to determine if the cause is related to a failed business rule or a technical or development bug.

Installing BDD into a Visual Studio Unit Test Project

To be able to use Fluent Assertions to develop BDD tests you will require installation of the FluentAssertions NuGet package.

Below is the screenshot of the NuGet package in the Package Manager:

All Fluent Assertions tests are included within test methods contained within an existing unit test class.

To be able to use the Fluent Assertions library within an NUnit test class requires the following namespace in your unit test source files:

using FluentAssertions;

Using Assertion Scopes

In an NUnit unit test we are familiar with the following pattern that is used to assert test conditions:

Assert.AreEqual(1, result.Count);

The above will work in NUnit, however if we try the equivalent Assert using Fluent Assertions:

Assert.IsTrue(result.Should().HaveCount(1).Equals(true));

This will not work as expected. We will get an invalid return value.

The structure we need to use is an assertion scope to wrap the assertion within a disposable block:           

using (new AssertionScope())
{
  .. your fluent assertion(s) here .. 

  Assert.Pass();
}

To use assertion scopes will require the inclusion of the following namespace:

using FluentAssertions.Execution;

Our unit test to list the books looks as follows:

[Test]
public void ListBooksTest() 
{
  var book = new BookViewModel() { ID = 1, Author = "W.Smith", 
    Title = "Rivers Run Dry", YearPublished = 1954 };
  context.Add(book);
  context.SaveChanges();

  book = new BookViewModel() { ID = 2, Author = "D.Lee", 
     Title = "Red Mine", YearPublished = 1968 };
  context.Add(book);
  context.SaveChanges();

  book = new BookViewModel() { ID = 3, Author = "V.Prescott", 
     Title = "Boundary Rider", YearPublished = 1974 };
  context.Add(book);
  context.SaveChanges();

  var bookService = new BookService(context, null);
  var books = bookService.GetBooks().GetAwaiter();

  var result = books.GetResult();

  using (new AssertionScope())
  {
    result.Should().HaveCount(3);
    Assert.Pass();
  }
}

Assessing Test Results within the Test Explorer

Whenever a fluent assertion runs without error it will continue onto the next line of code, and in the above code will pass the unit test.

Whenever a fluent assertion runs and fails an assertion (and throws an exception), it will continue until all subsequent fluent assertions are run within the assertion scope and return a list of exceptions.

If an assertion fails within one of the unit tests, we will see the error message shown in the test explorer:

A standard NUnit unit test contains a number of test assertions.

{
  Assert.IsTrue({some condition 1})
  Assert.IsTrue({some condition 2})
	..
  Assert.IsTrue({some condition N})
}

The above throws an error when the first assertion fails. With fluent assertions we can combine the assertions and have any errors be silently collected at the end of an assertion scope block:

using (new AssertionScope())
{
  Subject1.Should()..

  Subject2.Should()..

  ..
  SubjectN.Should()..

  Assert.Pass();
}

When the unit test is run, any errors that show up in the test explorer as shown will be combined in a summary message:

Message: Did not expect loanReturnResult.Item1.LoanedBy to be empty.Did not expect 
loanReturnResult.Item1.DateDue.DayOfYear to be 126.

As we have seen, Fluent Assertions is quite a powerful BDD testing package that can help business and test analysts work more effectively with developers to produce more effective application unit tests that are self-documenting.  

I hope you found this post useful and informative.

For further details, the link to Fluent Assertions is here:

https://fluentassertions.com/introduction

shows more details and examples on how to use this BDD tool.

I will look at other BDD test tools in a future post and how to integrate BDD tools into Continuous Integration DevOps tools like Azure DevOps or TeamCity.

That is all for today’s post.

I hope you found this post enjoyable and informative.

Social media & sharing icons powered by UltimatelySocial