Section 4 of 5

WebApplicationFactory

🎯 What You'll Learn

  • What is WebApplicationFactory
  • Testing HTTP endpoints
  • Creating test server
  • Making HTTP requests
  • Testing full application

What is WebApplicationFactory?

WebApplicationFactory creates an in-memory test server for testing your entire ASP.NET Core application, including HTTP endpoints, middleware, and routing.

Setup

Install Package Bash
dotnet add package Microsoft.AspNetCore.Mvc.Testing
Make Program.cs Testable C#
// Add at end of Program.cs
public partial class Program { }

Creating Test Class

ProductsControllerTests.cs C#
public class ProductsControllerTests 
    : IClassFixture<WebApplicationFactory<Program>>
{
    private readonly WebApplicationFactory<Program> _factory;

    public ProductsControllerTests(WebApplicationFactory<Program> factory)
    {
        _factory = factory;
    }
}

Testing GET Endpoints

Test GET Request C#
[Fact]
public async Task Get_Products_ReturnsSuccessStatusCode()
{
    // Arrange
    var client = _factory.CreateClient();

    // Act
    var response = await client.GetAsync("/api/products");

    // Assert
    response.EnsureSuccessStatusCode(); // 200-299
    Assert.Equal("application/json; charset=utf-8", 
        response.Content.Headers.ContentType.ToString());
}

Testing POST Endpoints

Test POST Request C#
[Fact]
public async Task Post_CreateProduct_ReturnsCreatedProduct()
{
    // Arrange
    var client = _factory.CreateClient();
    var product = new Product { Name = "Test Product", Price = 99 };
    var content = new StringContent(
        JsonSerializer.Serialize(product),
        Encoding.UTF8,
        "application/json");

    // Act
    var response = await client.PostAsync("/api/products", content);

    // Assert
    response.EnsureSuccessStatusCode();
    var responseString = await response.Content.ReadAsStringAsync();
    var createdProduct = JsonSerializer.Deserialize<Product>(responseString);
    
    Assert.NotNull(createdProduct);
    Assert.Equal("Test Product", createdProduct.Name);
}

Custom WebApplicationFactory

Customize the factory to use in-memory database.

CustomWebApplicationFactory.cs C#
public class CustomWebApplicationFactory : WebApplicationFactory<Program>
{
    protected override void ConfigureWebHost(IWebHostBuilder builder)
    {
        builder.ConfigureServices(services =>
        {
            // Remove real database
            var descriptor = services.SingleOrDefault(
                d => d.ServiceType == typeof(DbContextOptions<InvenTrackDbContext>));

            if (descriptor != null)
                services.Remove(descriptor);

            // Add in-memory database
            services.AddDbContext<InvenTrackDbContext>(options =>
                options.UseInMemoryDatabase("TestDb"));
        });
    }
}

Key Takeaways

  • WebApplicationFactory: In-memory test server
  • IClassFixture: Share factory across tests
  • CreateClient(): Get HttpClient for requests
  • EnsureSuccessStatusCode(): Assert 200-299
  • Custom factory: Override ConfigureWebHost
  • Full integration: Tests entire application