Tuesday, December 2, 2025

thumbnail

Unit Testing ASP.NET Core Applications

 Unit Testing ASP.NET Core Applications


Unit testing ensures your ASP.NET Core application is reliable, maintainable, and resilient to changes. ASP.NET Core has excellent built-in support for testing using frameworks like xUnit, NUnit, and MSTest, with xUnit being the default choice in Microsoft templates.


This guide explains how to set up, write, and run effective unit tests for controllers, services, and repositories.


๐Ÿ“ฆ 1. Tools and Libraries You’ll Need

✔ Test Frameworks


xUnit (recommended, default in new templates)


NUnit


MSTest


✔ Mocking Libraries


Moq (most popular)


NSubstitute


FakeItEasy


✔ Assertion Libraries (optional)


FluentAssertions


✔ ASP.NET Core Testing Packages

<PackageReference Include="Microsoft.NET.Test.Sdk" Version="*" />

<PackageReference Include="xunit" Version="*" />

<PackageReference Include="xunit.runner.visualstudio" Version="*" />

<PackageReference Include="Moq" Version="*" />


๐Ÿงฑ 2. Create a Test Project


In Visual Studio or CLI:


Using CLI:

dotnet new xunit -o MyApp.Tests

cd MyApp.Tests

dotnet add reference ../MyApp/MyApp.csproj



This creates an xUnit project and references your ASP.NET Core project.


๐Ÿงช 3. Basic Structure of a Unit Test


Example using xUnit:


using Xunit;


public class MathTests

{

    [Fact]

    public void Add_ReturnsCorrectResult()

    {

        var result = 2 + 3;

        Assert.Equal(5, result);

    }

}


๐Ÿง  4. Unit Testing Services (Best Starting Point)


Example service:


public interface ICalculatorService

{

    int Add(int a, int b);

}


public class CalculatorService : ICalculatorService

{

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

}


Test:

public class CalculatorServiceTests

{

    [Fact]

    public void Add_ReturnsSum()

    {

        var service = new CalculatorService();

        var result = service.Add(5, 7);


        Assert.Equal(12, result);

    }

}



Services are easy to test because they have no HTTP or UI logic.


๐Ÿ”ง 5. Unit Testing Controllers


Controllers should be thin, delegating most logic to services.

You unit test controllers by mocking services.


Example controller:


[ApiController]

[Route("api/[controller]")]

public class WeatherController : ControllerBase

{

    private readonly IWeatherService _service;


    public WeatherController(IWeatherService service)

    {

        _service = service;

    }


    [HttpGet("{city}")]

    public IActionResult GetWeather(string city)

    {

        var weather = _service.GetWeather(city);

        if (weather == null) return NotFound();

        return Ok(weather);

    }

}


Test with Moq:

public class WeatherControllerTests

{

    [Fact]

    public void GetWeather_ReturnsOk_WhenWeatherExists()

    {

        var mock = new Mock<IWeatherService>();

        mock.Setup(m => m.GetWeather("London"))

            .Returns("Sunny");


        var controller = new WeatherController(mock.Object);


        var result = controller.GetWeather("London") as OkObjectResult;


        Assert.NotNull(result);

        Assert.Equal("Sunny", result.Value);

    }

}


๐Ÿ—„️ 6. Unit Testing Repositories


Repositories typically access the database.

For unit tests, you mock the repository dependencies.


Example repository interface:


public interface IUserRepository

{

    User GetById(int id);

}



Mocking with Moq:


var mockRepo = new Mock<IUserRepository>();

mockRepo.Setup(r => r.GetById(1)).Returns(new User { Id = 1, Name = "Alice" });



If you want real DB behavior, use integration testing with EF Core InMemory (covered below).


๐Ÿงช 7. Testing with EF Core InMemory (Light Integration Testing)


EF Core provides an InMemory provider for predictable tests.


public class UserRepositoryTests

{

    [Fact]

    public void GetById_ReturnsUser()

    {

        var options = new DbContextOptionsBuilder<AppDbContext>()

            .UseInMemoryDatabase("TestDb")

            .Options;


        using var context = new AppDbContext(options);

        context.Users.Add(new User { Id = 1, Name = "Alice" });

        context.SaveChanges();


        var repo = new UserRepository(context);

        var user = repo.GetById(1);


        Assert.Equal("Alice", user.Name);

    }

}



This approach tests more realistic EF behavior without using a real SQL server.


๐ŸŒ 8. Testing ASP.NET Core HTTP Endpoints (Minimal API)


For minimal APIs, you can test endpoints via the app itself.


Example:


var app = new WebApplicationFactory<Program>();

var client = app.CreateClient();

var response = await client.GetAsync("/weather/London");



(This is technically integration testing, not pure unit testing.)


๐Ÿงฉ 9. Using FluentAssertions for Cleaner Tests


Instead of:


Assert.Equal(5, result);



You write:


result.Should().Be(5);



FluentAssertions improves readability.


๐Ÿš€ 10. Running Tests

CLI:

dotnet test


Visual Studio:


Test Explorer → Run All Tests


Live test results inside the IDE


๐Ÿ Summary: Best Practices


✔ Keep logic in services so controllers stay simple

✔ Mock dependencies with Moq

✔ Use EF Core InMemory for lightweight DB tests

✔ Use xUnit for clean, modern testing

✔ Use FluentAssertions for readable assertions

✔ Write small, fast, isolated tests

✔ Run tests automatically in CI pipelines


๐ŸŽฏ Conclusion


Unit testing ASP.NET Core applications helps ensure robustness and maintainability.

With xUnit, Moq, and EF Core InMemory, writing effective tests becomes straightforward and highly productive.

Start with services → controllers → repositories, and build up a reliable testing suite.

Learn Dot Net Course in Hyderabad

Read More

Testing and Debugging

Managing Application State in React with Redux and ASP.NET Core

Component-Based Development in Blazor

Introduction to TailwindCSS for Full Stack .NET Developers

Visit Our Quality Thought Institute in Hyderabad

Get Directions 

Subscribe by Email

Follow Updates Articles from This Blog via Email

No Comments

About

Search This Blog

Powered by Blogger.

Blog Archive