Unit Testing with xUnit in .NET: Complete Beginner's Guide
Writing code is only part of software development. Ensuring that code works correctly and continues to work after future changes is equally important.
Unit testing helps developers verify that individual components behave as expected. In the .NET ecosystem, xUnit is one of the most popular testing frameworks and is widely used in professional applications.
In this guide, you'll learn how to create unit tests with xUnit, write assertions, test business logic, mock dependencies, and follow testing best practices.
- What Is Unit Testing?
- Why Unit Tests Matter
- Installing xUnit
- Creating Test Projects
- Writing Test Methods
- Using Assertions
- Testing Services
- Mocking Dependencies
- Common Mistakes
- Best Practices
What Is Unit Testing?
Unit testing is the process of testing small pieces of code, usually individual methods or classes, in isolation.
The goal is to verify that each unit behaves correctly under different conditions.
Benefits of Unit Testing
- Detect bugs early.
- Improve code quality.
- Increase confidence when refactoring.
- Reduce manual testing effort.
- Improve maintainability.
Create a Test Project
Create a new xUnit project using the .NET CLI.
dotnet new xunit -n MyApp.Tests
Add the test project to your solution.
dotnet sln add MyApp.Tests
Project Structure
MyApp
│
├── Services
│ └── CalculatorService.cs
│
MyApp.Tests
│
└── CalculatorServiceTests.cs
Create a Service to Test
public class CalculatorService
{
public int Add(int a, int b)
{
return a + b;
}
}
Write Your First xUnit Test
using Xunit;
public class CalculatorServiceTests
{
[Fact]
public void Add_ReturnsCorrectResult()
{
var calculator =
new CalculatorService();
int result =
calculator.Add(5, 3);
Assert.Equal(8, result);
}
}
The Fact attribute identifies a test method.
Running Tests
dotnet test
The test runner executes all test methods and reports successful and failed tests.
Understanding Assertions
Assertions verify expected outcomes.
Assert.Equal(10, result);
Assert.True(isValid);
Assert.False(hasErrors);
Assert.NotNull(user);
Assert.Contains("Admin", roles);
Testing Multiple Inputs
Use Theory and InlineData to test several scenarios.
[Theory]
[InlineData(2, 3, 5)]
[InlineData(10, 5, 15)]
[InlineData(1, 1, 2)]
public void Add_ReturnsExpectedResult(
int a,
int b,
int expected)
{
var calculator =
new CalculatorService();
int result =
calculator.Add(a, b);
Assert.Equal(expected, result);
}
Testing Exceptions
[Fact]
public void Divide_ByZero_ThrowsException()
{
Assert.Throws<DivideByZeroException>(
() => 10 / int.Parse("0"));
}
Testing Business Logic
public class DiscountService
{
public decimal ApplyDiscount(
decimal price)
{
return price * 0.9m;
}
}
[Fact]
public void ApplyDiscount_Returns10PercentOff()
{
var service =
new DiscountService();
decimal result =
service.ApplyDiscount(100);
Assert.Equal(90, result);
}
Mocking Dependencies
Real applications often depend on databases, APIs, or external services.
Mocking allows tests to run without relying on external systems.
Install Moq
dotnet add package Moq
Example Interface
public interface IEmailService
{
void Send(string message);
}
Mock the Dependency
using Moq;
var emailMock =
new Mock<IEmailService>();
emailMock
.Setup(e => e.Send(It.IsAny<string>()));
Mock objects simulate behavior without sending actual emails or connecting to databases.
Unit Testing in ASP.NET Core
Unit testing is commonly used for:
- Services
- Business Logic
- Repositories
- Validation Rules
- Controllers
Common Beginner Mistakes
- Testing multiple behaviors in one test.
- Writing overly complex tests.
- Testing database infrastructure directly.
- Ignoring edge cases.
- Using unclear test names.
Best Practices
- Keep tests small and focused.
- Test one behavior per test method.
- Use descriptive test names.
- Mock external dependencies.
- Run tests automatically in CI/CD pipelines.
- Maintain high test coverage for business logic.
Frequently Asked Questions
What is xUnit?
xUnit is a popular open-source testing framework for .NET applications.
Is xUnit better than MSTest?
Both are good frameworks. xUnit is widely adopted in modern .NET projects and has strong community support.
Should I test controllers?
Focus primarily on business logic and services. Controllers can be tested when they contain important logic.
What percentage of code should be tested?
There is no perfect number, but critical business logic should have strong test coverage.
Related Tutorials
- Dependency Injection in ASP.NET Core
- Repository Pattern in ASP.NET Core
- Entity Framework Core CRUD
- Build a REST API in ASP.NET Core
- Exception Handling in C#
- Best C# Coding Practices
Conclusion
Unit testing is an essential skill for every .NET developer. It helps prevent bugs, improve maintainability, and increase confidence when making changes to an application.
By learning xUnit, assertions, mocking, and testing best practices, you'll be able to create more reliable ASP.NET Core and .NET applications.