unit testing
development

Unit Testing in .NET with xUnit: A Complete Tutorial (Made Super Simple)

Let’s be real, bugs in code are annoying. They break stuff, cause late-night headaches, and often lead to endless Slack messages asking, “Why is this broken?” One of the best ways to avoid all that drama? Unit testing.

In this guide, we’ll walk through unit testing in .NET using xUnit, one of the most popular testing libraries out there. Don’t worry, we’ll keep it friendly, simple, and beginner-approved.

What’s Unit Testing Anyway?

Unit testing is all about testing individual pieces of code, usually methods or functions, to make sure they behave correctly. Think of it like checking each Lego block before building the entire castle.

Here’s why unit tests matter:

  •  Catch bugs early
  •  Improve code reliability
  •  Make refactoring safer
  •  Document expected behaviour

 Why Use xUnit for .NET?

.NET supports a few testing frameworks, but xUnit stands out for being:

  • Open-source and super fast
  • Clean and readable syntax
  • Fully supported by Microsoft
  • Easy to integrate with test runners and CI/CD pipelines

Setting Up xUnit in Your .NET Project

Okay, enough talk, let’s get to work.

1. Create a .NET Solution

If you don’t already have a .NET project, go ahead and create one:

bash

CopyEdit

dotnet new sln -n MyApp

dotnet new classlib -n MyApp.Core

dotnet new xunit -n MyApp.Tests

dotnet sln add MyApp.Core/MyApp.Core.csproj

dotnet sln add MyApp.Tests/MyApp.Tests. csproj

2. Add a Reference to the Main Project

Your test project needs to “know” about your app code:

bash

CopyEdit

dotnet add MyApp.Tests/MyApp.Tests.csproj reference MyApp.Core/MyApp.Core.csproj

That’s it! Now you’re ready to write your first test.

Writing Your First xUnit Test

Let’s say you’ve got a simple calculator:

csharp

CopyEdit

// File: Calculator.cs

namespace MyApp.Core

{

    public class Calculator

    {

        public int Add(int a, int b) => a + b;

    }

}

Here’s how you test it using xUnit:

csharp

CopyEdit

// File: CalculatorTests.cs

using MyApp.Core;

using Xunit;

namespace MyApp.Tests

{

    public class CalculatorTests

    {

        [Fact]

        public void Add_ShouldReturnCorrectSum()

        {

            // Arrange

            var calc = new Calculator();

            // Act

            int result = calc.Add(2, 3);

            // Assert

            Assert.Equal(5, result);

        }

    }

}

What’s Going On?

  • [Fact] tells xUnit that this is a test method.
  • Arrange, Act, Assert is the golden pattern for writing clean, clear tests.

Running the Tests

To run your tests, just use the command:

bash

CopyEdit

dotnet test

You’ll get output like:

bash

CopyEdit

Passed! 1 test ran in 50ms.

And just like that, you’ve written and passed your first unit test!

xUnit Attributes You Should Know

Here are some of the key attributes you’ll use often:

AttributeWhat it does
[Fact]Marks a basic test method
[Theory]Used for parameterised tests
[InlineData]Provides test data for Theory

Example of a [Theory] test:

csharp

CopyEdit

[Theory]

[InlineData(2, 3, 5)]

[InlineData(-1, -1, -2)]

public void Add_MultipleValues_ShouldWork(int a, int b, int expected)

{

    var calc = new Calculator();

    int result = calc.Add(a, b);

    Assert.Equal(expected, result);

}

Common Testing Scenarios

Here’s how to handle real-life stuff you’ll face in testing.

 Testing for Exceptions

csharp

CopyEdit

[Fact]

public void Divide_ByZero_ShouldThrow()

{

    var calc = new Calculator();

    Assert.Throws<DivideByZeroException>(() => calc.Divide(10, 0));

}

 Testing Asynchronous Methods

csharp

CopyEdit

[Fact]

public async Task GetDataAsync_ShouldReturnData()

{

    var service = new DataService();

    var data = await service.GetDataAsync();

    Assert.NotNull(data);

}

Mocking with Moq (Bonus Tip)

Sometimes your methods depend on external stuff like databases or APIs. That’s where mocking comes in. A popular tool is Moq.

Install it:

bash

CopyEdit

dotnet add package Moq

Basic usage:

csharp

CopyEdit

var mockRepo = new Mock<IUserRepository>();

mockRepo.Setup(repo => repo.GetUser(1)).Returns(new User { Id = 1, Name = “Alice” });

You can then inject that mock into your service and test it without hitting the real database.

Best Practices for Unit Testing

  • Keep tests isolated – test one thing at a time
  • Use meaningful names – describe what the test checks
  • Avoid magic numbers – use variables or constants
  • Don’t over-mock – only mock when needed
  • Run tests often – make it part of your dev flow

FAQs

Q1: Can I use xUnit with .NET 6 or 7?

Absolutely! xUnit works great with both.

Q2: What’s the difference between xUnit, NUnit, and MSTest?

They’re all testing frameworks, but xUnit is newer, cleaner, and recommended by the .NET team.

Q3: How do I run tests in Visual Studio?

Just right-click the test project or method and click “Run Tests”. Or use the Test Explorer panel.

 Wrapping Things Up

So, that’s the scoop on unit testing in .NET with xUnit. It’s not rocket science, but it is rocket fuel for your code quality. From setting up a test project to writing and running tests, you’re now equipped to make your .NET apps more robust and reliable.

Leave a Reply

Your email address will not be published. Required fields are marked *