.NET Core  

How to Implement Unit Testing in .NET using xUnit with Example

Introduction

In modern software development, writing code is only half of the job. Ensuring that the code behaves correctly under different scenarios is equally important. This is where unit testing in .NET using xUnit plays a critical role.

Unit testing allows developers to test individual components (methods, classes, or functions) in isolation. It helps catch bugs early, improves code quality, and builds confidence while making changes.

In this article, we will understand how to implement unit testing in .NET using xUnit step by step, along with real-world examples and proper explanations.

What is Unit Testing?

Unit testing is a software testing technique where individual units of code are tested independently to verify that they work as expected.

A “unit” can be:

  • A method

  • A class

  • A small piece of logic

Why Unit Testing is Important

  • Detects bugs early in development

  • Improves code reliability

  • Makes refactoring safer

  • Helps in maintaining large applications

What is xUnit in .NET?

xUnit is a popular testing framework for .NET applications. It is widely used for writing automated tests in ASP.NET Core and C# projects.

Key Features of xUnit

  • Simple and clean syntax

  • Strong support for dependency injection

  • Parallel test execution

  • Highly maintainable test structure

Step 1: Create a .NET Project

First, create a simple .NET project.

dotnet new console -n CalculatorApp

Explanation

  • This command creates a new console application

  • We will use this project to write business logic and test it

Step 2: Add xUnit Test Project

Now create a test project using xUnit.

dotnet new xunit -n CalculatorApp.Tests

Explanation

  • This creates a separate test project

  • Best practice is to keep tests in a separate project

Step 3: Add Project Reference

Link the main project with the test project.

dotnet add CalculatorApp.Tests reference CalculatorApp

Explanation

  • This allows test project to access application code

  • Without this, tests cannot call your methods

Step 4: Create a Sample Class to Test

Inside the main project, create a simple calculator.

public class Calculator
{
    public int Add(int a, int b)
    {
        return a + b;
    }

    public int Divide(int a, int b)
    {
        if (b == 0)
            throw new ArgumentException("Division by zero is not allowed");

        return a / b;
    }
}

Explanation

  • Add method returns sum of two numbers

  • Divide method handles division and throws exception for invalid input

Step 5: Write Unit Tests using xUnit

Now write test cases in the test project.

using Xunit;

public class CalculatorTests
{
    [Fact]
    public void Add_ShouldReturnCorrectSum()
    {
        var calculator = new Calculator();

        var result = calculator.Add(2, 3);

        Assert.Equal(5, result);
    }

    [Fact]
    public void Divide_ShouldThrowException_WhenDivideByZero()
    {
        var calculator = new Calculator();

        Assert.Throws<ArgumentException>(() => calculator.Divide(10, 0));
    }
}

Explanation

[Fact]

  • Indicates a test method

  • xUnit executes methods marked with this attribute

Assert.Equal

  • Verifies expected result matches actual result

Assert.Throws

  • Verifies that an exception is thrown

This is a standard xUnit testing example in .NET.

Step 6: Run Unit Tests

Run tests using CLI:

dotnet test

Explanation

  • Executes all test cases

  • Shows passed and failed tests

  • Helps identify issues quickly

Real-World Scenario

Consider an e-commerce application:

  • Price calculation logic must be accurate

  • Discount logic must not fail

Unit tests ensure:

  • Correct calculations

  • No unexpected behavior

Best Practices for Unit Testing in .NET

Keep Tests Independent

Each test should not depend on another test.

Use Meaningful Test Names

Example:

Add_ShouldReturnCorrectSum

Test Edge Cases

  • Null values

  • Invalid inputs

  • Boundary conditions

Follow Arrange-Act-Assert Pattern

  • Arrange → Setup

  • Act → Execute

  • Assert → Verify

Common Mistakes

Testing Multiple Things in One Test

Makes debugging difficult.

Not Testing Edge Cases

Leads to production bugs.

Writing Tests After Deployment

Tests should be written during development.

Advantages of Unit Testing using xUnit

  • Improves code quality

  • Reduces bugs

  • Enables safe refactoring

  • Supports automation in CI/CD pipelines

Limitations

  • Initial setup takes time

  • Requires discipline

  • Does not replace integration testing

Summary

The difference between readonly and const in C# lies in when and how their values are assigned. Const is used for values that are completely fixed and known at compile time, while readonly is used for values that are assigned at runtime but should not change afterward. Choosing the right keyword helps improve code clarity, performance, and maintainability in ASP.NET Core and C# applications.