An Introduction to Unit Testing in .NET Core with xUnit
A beginner's guide to unit testing in .NET Core using the popular xUnit.net framework. Learn how to set up a test project, write your first tests with Facts and Theories, and follow the Arrange-Act-Assert pattern.
Writing automated tests is a cornerstone of professional software development. Tests verify that your code works as expected, prevent regressions, and act as living documentation for your application. In the .NET ecosystem, the most popular framework for writing unit tests is xUnit.net.
xUnit is a free, open-source, community-focused testing framework that is simple, expressive, and extensible. It's the standard choice for testing .NET Core applications.
Why xUnit?
While other frameworks like MSTest and NUnit exist, xUnit has gained popularity for its clean design and focus on test isolation. A key feature of xUnit is that it creates a new instance of the test class for every single test method, which prevents tests from interfering with each other by sharing state.
Setting Up a Test Project
The .NET Core CLI makes it incredibly easy to get started. To create a new xUnit test project, you can run the following command:
dotnet new xunit -n MyProject.Tests
This command creates a new project that is already configured with the xUnit runner and dependencies.
The Arrange-Act-Assert Pattern
A well-structured unit test follows a simple pattern called Arrange, Act, Assert (AAA):
- Arrange: Set up the objects and variables that you need for the test.
- Act: Execute the method or piece of code that you want to test.
- Assert: Check that the result of the action is what you expected.
This pattern makes your tests clear, readable, and easy to understand.
Writing Your First Test: [Fact]
The most basic type of test in xUnit is a Fact. A fact is a test that should always be true. You declare a test method as a fact by decorating it with the [Fact]
attribute.
Let's say we have a simple Calculator
class in our main application:
public class Calculator
{
public int Add(int a, int b) => a + b;
}
Now, let's write a test for it in our test project:
using Xunit;
public class CalculatorTests
{
[Fact]
public void Add_ShouldReturnCorrectSum()
{
// Arrange
var calculator = new Calculator();
// Act
var result = calculator.Add(2, 3);
// Assert
Assert.Equal(5, result);
}
}
The Assert.Equal()
method is one of many assertion methods provided by xUnit to verify outcomes.
Data-Driven Tests with [Theory]
Often, you'll want to run the same test logic with several different sets of input data. Instead of writing a separate test for each one, you can use a Theory. A theory is a test that is true for a specific set of data.
You decorate the test method with [Theory]
and provide the data using attributes like [InlineData]
.
[Theory]
[InlineData(1, 2, 3)]
[InlineData(-1, -1, -2)]
[InlineData(0, 5, 5)]
public void Add_ShouldReturnCorrectSum_ForMultipleInputs(int a, int b, int expected)
{
// Arrange
var calculator = new Calculator();
// Act
var result = calculator.Add(a, b);
// Assert
Assert.Equal(expected, result);
}
xUnit will run this test method three times, once for each [InlineData]
attribute, passing the values as arguments to the method. This is a powerful way to test multiple scenarios concisely.
Running Your Tests
You can run your tests from the command line in your test project's directory:
dotnet test
The .NET test runner will discover and execute your xUnit tests and report the results.
Conclusion
Unit testing is an essential discipline for writing high-quality software. xUnit.net provides a simple and powerful framework for writing and running your tests in .NET Core. By using Facts and Theories and following the Arrange-Act-Assert pattern, you can write clean, readable, and effective tests that will give you confidence in your code.