Software Testing  

Unit Testing and Integration Testing in .NET Core

Introduction

Testing is a critical part of software development. It ensures that your application works as expected, prevents regressions, and increases confidence in deployments. In .NET Core, developers typically use two main types of tests:

  • Unit Testing → Tests individual components (methods, classes) in isolation.

  • Integration Testing → Tests how different components work together, often involving databases, APIs, or external services.

This article explains both concepts with real-time examples.

Unit Testing in .NET Core

What is Unit Testing?

Unit testing focuses on small, isolated pieces of code. It ensures that a method or class behaves correctly under different conditions.

Tools Commonly Used

  • xUnit (popular testing framework)

  • MSTest (Microsoft’s testing framework)

  • NUnit (another widely used framework)

  • Moq (for mocking dependencies)

Example: Testing a Calculator Service

Step 1: Create the Service

public class CalculatorService
{
    public int Add(int a, int b) => a + b;
    public int Subtract(int a, int b) => a - b;
}

Step 2: Create Unit Test Project

dotnet new xunit -n CalculatorTests
dotnet add CalculatorTests reference MyApp

Step 3: Write Unit Tests

public class CalculatorServiceTests
{
    private readonly CalculatorService _calculator = new();

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

    [Fact]
    public void Subtract_ReturnsCorrectDifference()
    {
        var result = _calculator.Subtract(5, 3);
        Assert.Equal(2, result);
    }
}

These tests run quickly and validate the logic of the CalculatorService.

Integration Testing in .NET Core

What is Integration Testing?

Integration testing ensures that multiple components work together correctly. Unlike unit tests, integration tests often involve:

  • Database access

  • API endpoints

  • Middleware and routing

Example: Testing a Web API with EF Core

Step 1: Create a Customer Model

public class Customer
{
    public int Id { get; set; }
    public string Name { get; set; }
}

Step 2: Create DbContext

public class AppDbContext : DbContext
{
    public AppDbContext(DbContextOptions<AppDbContext> options) : base(options) { }
    public DbSet<Customer> Customers { get; set; }
}

Step 3: Create API Controller

[ApiController]
[Route("api/[controller]")]
public class CustomersController : ControllerBase
{
    private readonly AppDbContext _context;

    public CustomersController(AppDbContext context)
    {
        _context = context;
    }

    [HttpGet]
    public IActionResult GetAll() => Ok(_context.Customers.ToList());
}

Step 4: Create Integration Test Project

dotnet new xunit -n IntegrationTests
dotnet add IntegrationTests reference MyApp

Step 5: Write Integration Test

public class CustomersApiTests : IClassFixture<WebApplicationFactory<Program>>
{
    private readonly HttpClient _client;

    public CustomersApiTests(WebApplicationFactory<Program> factory)
    {
        _client = factory.CreateClient();
    }

    [Fact]
    public async Task GetAll_ReturnsCustomers()
    {
        var response = await _client.GetAsync("/api/customers");
        response.EnsureSuccessStatusCode();

        var content = await response.Content.ReadAsStringAsync();
        Assert.Contains("Name", content); // Checks if response contains customer data
    }
}

Here, WebApplicationFactory<Program> spins up a test server that mimics the real application, allowing full API testing.

Key Differences Between Unit and Integration Testing

FeatureUnit TestingIntegration Testing
ScopeSingle method/classMultiple components working together
SpeedVery fastSlower (involves I/O, DB, APIs)
DependenciesMockedReal or test versions
PurposeValidate logicValidate system behavior
ExampleCalculator methodAPI endpoint with DB

Conclusion

Unit testing and integration testing complement each other in .NET Core projects. Unit tests ensure individual components work correctly, while integration tests validate end-to-end workflows. Together, they provide confidence that your application is reliable, maintainable, and production-ready.