Introduction to Unit Testing in .NET

Unit testing is a crucial practice in modern software development, especially for .NET applications. It involves testing individual units of code, typically methods or functions, in isolation to verify that they behave as expected. This helps in catching bugs early, improving code quality, and enabling confident refactoring.

Why Unit Test?

Common .NET Unit Testing Frameworks

The .NET ecosystem offers several popular unit testing frameworks. The most widely used include:

Writing Your First Unit Test (using xUnit.net)

Let's create a simple example. Suppose we have a class that performs basic arithmetic operations:


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

    public int Subtract(int a, int b)
    {
        return a - b;
    }
}
            

Now, let's write a unit test for the Add method using xUnit.net. You'll need to add the xUnit.net NuGet packages to your test project.


using Xunit;

public class CalculatorTests
{
    [Fact]
    public void Add_TwoPositiveNumbers_ReturnsCorrectSum()
    {
        // Arrange
        var calculator = new Calculator();
        int num1 = 5;
        int num2 = 10;
        int expectedSum = 15;

        // Act
        int actualSum = calculator.Add(num1, num2);

        // Assert
        Assert.Equal(expectedSum, actualSum);
    }

    [Theory]
    [InlineData(2, 3, 5)]
    [InlineData(-1, 1, 0)]
    [InlineData(0, 0, 0)]
    public void Add_VariousNumbers_ReturnsCorrectSum(int num1, int num2, int expectedSum)
    {
        // Arrange
        var calculator = new Calculator();

        // Act
        int actualSum = calculator.Add(num1, num2);

        // Assert
        Assert.Equal(expectedSum, actualSum);
    }
}
            

Tip: Arrange, Act, Assert (AAA) Pattern

Unit tests commonly follow the Arrange, Act, Assert pattern:

  • Arrange: Set up the test environment and input data.
  • Act: Execute the code under test.
  • Assert: Verify that the outcome matches the expected result.

Key Concepts in Unit Testing

Example: Testing for Exceptions

You can also test if your code throws expected exceptions:


using Xunit;
using System;

public class CalculatorTests
{
    [Fact]
    public void Divide_ByZero_ThrowsDivideByZeroException()
    {
        // Arrange
        var calculator = new Calculator();
        int numerator = 10;
        int denominator = 0;

        // Act & Assert
        Assert.Throws(() => calculator.Divide(numerator, denominator));
    }
}
                

Best Practices

By embracing unit testing, you can build more robust, maintainable, and reliable .NET applications.