C# Foundations·C# from first file to first API

Testing with xUnit

xUnit turns expectations into repeatable, runnable checks with dotnet test.

Beginner 14 min read Lesson 5 of 300 Challenge included
What you will be able to do
  • Structure each test as arrange, act, assert.
  • Use [Fact] for one case and [Theory] with InlineData for many.
  • Replace slow or external dependencies with test doubles.
  • Run dotnet test and keep every test green.

In plain English

xUnit is a .NET test framework where each [Fact] marks a single test and [Theory] runs one test across many sets of data. Arrange sets up the inputs, act calls the code, and assert checks the outcome. A test double is a stand-in that replaces a real dependency so tests stay fast and isolated. Run dotnet test from the command line to execute the whole suite.

Step by step

  1. 1Create a test project and add the xUnit package.
  2. 2Write a [Fact] that asserts a sum.
  3. 3Convert it to a [Theory] with InlineData rows.
  4. 4Assert that invalid input throws.
  5. 5Run dotnet test and read the result.
CalculatorTests.csC#
using Xunit;

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

    public int Divide(int a, int b)
    {
        if (b == 0) throw new ArgumentException("Cannot divide by zero");
        return a / b;
    }
}

public class CalculatorTests
{
    private readonly Calculator calculator = new Calculator();

    [Fact]
    public void Add_ReturnsSum()
    {
        var result = calculator.Add(2, 3);
        Assert.Equal(5, result);
    }

    [Theory]
    [InlineData(6, 3, 2)]
    [InlineData(9, 3, 3)]
    public void Divide_ReturnsQuotient(int a, int b, int expected)
    {
        Assert.Equal(expected, calculator.Divide(a, b));
    }

    [Fact]
    public void Divide_ByZero_Throws()
    {
        Assert.Throws<ArgumentException>(() => calculator.Divide(1, 0));
    }
}

Common mistakes

  • A test with no assert passes but verifies nothing.
  • Tests that touch a database or the network are slow and flaky.
  • Overusing [Theory] hides which case failed when the name is unclear.
  • Sharing mutable state between tests breaks isolation and ordering.
Your turn

Write a parameterised test

Easy

Write a [Theory] with two InlineData rows that verifies Add returns the expected sum.

CSHARP · starter
public class CalculatorTests
{
    [Fact]
    public void Add_ReturnsSum()
    {
        var calculator = new Calculator();
        Assert.Equal(5, calculator.Add(2, 3));
    }
}
Check your understanding before moving on.
Knowledge checkQuestion 1

What does [Fact] mark in xUnit?

Select an answer to continue
Study tools

Make it yours.

Keep a private note for this lesson, then turn the key ideas into flashcards you can revisit.

Sign in to save notes and flashcards.Both are private to your account and stay with your progress.
Sign in
Finished reading?

Lock in what you just learned.

Mark this lesson complete to save your place and move one step closer to the certificate.

Next: Types and nullability
Lesson 5 of 300 · 0% of course