Section 1 of 5

Unit Testing with xUnit

🎯 What You'll Learn

  • What is unit testing
  • Setting up xUnit
  • Writing tests with [Fact] and [Theory]
  • Assertions
  • Arrange-Act-Assert pattern

What is Unit Testing?

Unit testing tests individual units of code (methods, classes) in isolation to ensure they work correctly.

Setting Up xUnit

Create Test Project Bash
dotnet new xunit -n InvenTrack.Tests
dotnet add InvenTrack.Tests reference InvenTrack
Required Packages Bash
dotnet add package xunit
dotnet add package xunit.runner.visualstudio
dotnet add package Microsoft.NET.Test.Sdk

Writing Your First Test

CalculatorTests.cs C#
public class CalculatorTests
{
    [Fact]
    public void Add_TwoNumbers_ReturnsSum()
    {
        // Arrange
        var calculator = new Calculator();

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

        // Assert
        Assert.Equal(5, result);
    }
}

[Fact] vs [Theory]

[Fact] - Single Test

Fact Example C#
[Fact]
public void Product_WithValidData_IsCreated()
{
    var product = new Product { Name = "Laptop", Price = 999 };
    
    Assert.NotNull(product);
    Assert.Equal("Laptop", product.Name);
}

[Theory] - Multiple Test Cases

Theory Example C#
[Theory]
[InlineData(2, 3, 5)]
[InlineData(10, 20, 30)]
[InlineData(-5, 5, 0)]
public void Add_VariousInputs_ReturnsCorrectSum(int a, int b, int expected)
{
    var calculator = new Calculator();
    
    var result = calculator.Add(a, b);
    
    Assert.Equal(expected, result);
}

Common Assertions

Assertions C#
// Equality
Assert.Equal(expected, actual);
Assert.NotEqual(expected, actual);

// Null checks
Assert.Null(value);
Assert.NotNull(value);

// Boolean
Assert.True(condition);
Assert.False(condition);

// Collections
Assert.Empty(collection);
Assert.NotEmpty(collection);
Assert.Contains(item, collection);

// Exceptions
Assert.Throws<ArgumentException>(() => method());

// Type checks
Assert.IsType<Product>(obj);

InvenTrack Example

ProductServiceTests.cs C#
public class ProductServiceTests
{
    [Fact]
    public void CalculateDiscount_ValidProduct_ReturnsDiscountedPrice()
    {
        // Arrange
        var service = new ProductService();
        var product = new Product { Price = 100 };

        // Act
        var result = service.CalculateDiscount(product, 0.1m); // 10% discount

        // Assert
        Assert.Equal(90, result);
    }

    [Theory]
    [InlineData(100, 0.1, 90)]
    [InlineData(50, 0.2, 40)]
    [InlineData(200, 0.5, 100)]
    public void CalculateDiscount_VariousInputs_ReturnsCorrectPrice(
        decimal price, decimal discount, decimal expected)
    {
        var service = new ProductService();
        var product = new Product { Price = price };

        var result = service.CalculateDiscount(product, discount);

        Assert.Equal(expected, result);
    }
}

Running Tests

Run Tests Bash
dotnet test

Key Takeaways

  • Unit testing: Test individual units in isolation
  • xUnit: Popular .NET testing framework
  • [Fact]: Single test case
  • [Theory]: Multiple test cases with [InlineData]
  • Arrange-Act-Assert: Standard test pattern
  • Assert: Verify expected outcomes