AzureFunctions.IntegrationTests 1.0.1

dotnet add package AzureFunctions.IntegrationTests --version 1.0.1
                    
NuGet\Install-Package AzureFunctions.IntegrationTests -Version 1.0.1
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="AzureFunctions.IntegrationTests" Version="1.0.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="AzureFunctions.IntegrationTests" Version="1.0.1" />
                    
Directory.Packages.props
<PackageReference Include="AzureFunctions.IntegrationTests" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add AzureFunctions.IntegrationTests --version 1.0.1
                    
#r "nuget: AzureFunctions.IntegrationTests, 1.0.1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package AzureFunctions.IntegrationTests@1.0.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=AzureFunctions.IntegrationTests&version=1.0.1
                    
Install as a Cake Addin
#tool nuget:?package=AzureFunctions.IntegrationTests&version=1.0.1
                    
Install as a Cake Tool

AzureFunctions.IntegrationTests

NuGet License: MIT

A testing library for Azure Functions v4 (isolated worker process model) that provides a FunctionAppFactory similar to WebApplicationFactory in ASP.NET Core. This makes it easy to write integration tests for your Azure Functions without needing to start the actual Functions runtime.

Features

  • ๐Ÿš€ Easy to use - Similar API to WebApplicationFactory<T> that developers already know
  • ๐Ÿ” Auto-discovery - Automatically finds and invokes your Azure Functions
  • ๐Ÿงช In-memory testing - No need to start the Functions host or use HTTP
  • ๐ŸŽฏ Full dependency injection - Access to the service provider for testing
  • ๐Ÿ“ Route parameter support - Handles complex routes with parameters like {id}, {email}, etc.
  • โš™๏ธ Customizable - Virtual methods to override host configuration
  • ๐Ÿ”„ HttpClient integration - Use familiar HttpClient for testing

Installation

dotnet add package AzureFunctions.IntegrationTests

Quick Start

0. Modify Your Program.cs for Testability

First, expose the host creation logic in your Azure Functions project, add public partial class Program and expose the GetHost function

var host= GetHost(args);

host.Run();

public partial class Program { 

    public static IHost GetHost(string[] args)
    {
         var builder = FunctionsApplication.CreateBuilder(args);
        builder.ConfigureFunctionsWebApplication();
        builder.Services
            .AddApplicationInsightsTelemetryWorkerService()
            .ConfigureFunctionsApplicationInsights();
        return builder.Build();
    }

}

1. Basic Usage

using AzureFunctions.IntegrationTests;
using Xunit;

public class MyFunctionTests : IClassFixture<FunctionAppFactory<Program>>
{
    private readonly HttpClient _client;

    public MyFunctionTests(FunctionAppFactory<Program> factory)
    {
        _client = factory.CreateClient();
    }

    [Fact]
    public async Task GetUser_ReturnsOk()
    {
        // Act
        var response = await _client.GetAsync("/api/users/123");

        // Assert
        Assert.Equal(HttpStatusCode.OK, response.StatusCode);
    }
}

2. Accessing Services

public class MyFunctionTests : IClassFixture<FunctionAppFactory<Program>>
{
    private readonly FunctionAppFactory<Program> _factory;

    public MyFunctionTests(FunctionAppFactory<Program> factory)
    {
        _factory = factory;
    }

    [Fact]
    public void CanAccessServices()
    {
        // Arrange
        using var scope = _factory.Services.CreateScope();
        var myService = scope.ServiceProvider.GetRequiredService<IMyService>();

        // Act & Assert
        Assert.NotNull(myService);
    }
}

3. Custom Headers

[Fact]
public async Task PostUser_WithCustomHeaders_ReturnsCreated()
{
    // Arrange
    var client = _factory.CreateClient();
    client.DefaultRequestHeaders.Add("X-Tenant-Id", "test-tenant");

    var content = new StringContent(
        JsonSerializer.Serialize(new { name = "John" }),
        Encoding.UTF8,
        "application/json");

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

    // Assert
    Assert.Equal(HttpStatusCode.Created, response.StatusCode);
}

Advanced Usage

Custom Factory for Test Configuration

You can create a custom factory to override services or configuration:

public class CustomFunctionAppFactory : FunctionAppFactory<Program>
{
    protected override void ConfigureHostBuilder(IHostBuilder builder)
    {
        builder.ConfigureServices(services =>
        {
            // Replace a service with a mock
            services.AddScoped<IMyService, MockMyService>();

            // Add test-specific services
            services.AddSingleton<ITestDataSeeder, TestDataSeeder>();
        });

        builder.ConfigureAppConfiguration((context, config) =>
        {
            // Add test-specific configuration
            config.AddInMemoryCollection(new Dictionary<string, string>
            {
                ["ConnectionStrings:TestDb"] = "test-connection-string"
            });
        });
    }

    protected override void ConfigureEnvironment()
    {
        base.ConfigureEnvironment();

        // Set additional environment variables for testing
        Environment.SetEnvironmentVariable("TEST_MODE", "true");
    }
}

// Usage
public class MyTests : IClassFixture<CustomFunctionAppFactory>
{
    private readonly HttpClient _client;

    public MyTests(CustomFunctionAppFactory factory)
    {
        _client = factory.CreateClient();
    }

    [Fact]
    public async Task Test_WithMockedServices()
    {
        // Your test implementation
    }
}

Integration with xUnit Collection Fixtures

For sharing the factory across multiple test classes:

[CollectionDefinition("Function Collection")]
public class FunctionCollection : ICollectionFixture<FunctionAppFactory<Program>>
{
    // This class has no code, it's just a marker for xUnit
}

[Collection("Function Collection")]
public class UserTests
{
    private readonly HttpClient _client;

    public UserTests(FunctionAppFactory<Program> factory)
    {
        _client = factory.CreateClient();
    }

    [Fact]
    public async Task GetUser_ReturnsOk()
    {
        var response = await _client.GetAsync("/api/users/123");
        Assert.Equal(HttpStatusCode.OK, response.StatusCode);
    }
}

[Collection("Function Collection")]
public class ProductTests
{
    private readonly HttpClient _client;

    public ProductTests(FunctionAppFactory<Program> factory)
    {
        _client = factory.CreateClient();
    }

    [Fact]
    public async Task GetProduct_ReturnsOk()
    {
        var response = await _client.GetAsync("/api/products/456");
        Assert.Equal(HttpStatusCode.OK, response.StatusCode);
    }
}

Testing Route Parameters

The library automatically handles route parameters:

// Given an Azure Function with route: "users/{userId}/orders/{orderId}"
[Function("GetOrder")]
public IActionResult GetOrder(
    [HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "users/{userId}/orders/{orderId}")]
    HttpRequestData req,
    Guid userId,
    int orderId)
{
    // Function implementation
}

// Test
[Fact]
public async Task GetOrder_WithRouteParameters_ReturnsOk()
{
    var response = await _client.GetAsync(
        "/api/users/550e8400-e29b-41d4-a716-446655440000/orders/123");

    Assert.Equal(HttpStatusCode.OK, response.StatusCode);
}

How It Works

  1. Auto-Discovery: The factory scans your entry point assembly for Azure Functions (methods decorated with [Function] attribute)
  2. Host Creation: It discovers your GetHost() or CreateHostBuilder() method and creates the host
  3. Request Routing: When you make an HTTP request via the test client, it routes to the appropriate function
  4. Parameter Binding: Route parameters are automatically extracted and converted to the correct types
  5. Response Conversion: IActionResult responses are converted to HttpResponseMessage for easy assertion

Requirements

  • .NET 8.0 or later
  • Azure Functions v4 (isolated worker process model)
  • Your Azure Functions project must have a Program class with either:
    • public static IHost GetHost(string[] args) method, or
    • public static IHostBuilder CreateHostBuilder(string[] args) method

Supported Features

  • โœ… HTTP triggers (GET, POST, PUT, DELETE, PATCH, etc.)
  • โœ… Route parameters (string, int, Guid, DateTime, enum, and nullable types)
  • โœ… Query string parameters
  • โœ… Request headers
  • โœ… Request body
  • โœ… IActionResult responses (OkObjectResult, NotFoundResult, BadRequestResult, etc.)
  • โœ… Dependency injection
  • โœ… Custom configuration
  • โœ… Environment variables

Limitations

  • Only supports HTTP-triggered functions
  • Timer, Queue, Blob, and other trigger types are not supported
  • Does not test the actual HTTP binding (e.g., authentication middleware at the HTTP level)

Example Project Structure

MyAzureFunctionsApp/
โ”œโ”€โ”€ src/
โ”‚   โ”œโ”€โ”€ MyApp.API/                    # Your Azure Functions project
โ”‚   โ”‚   โ”œโ”€โ”€ Functions/
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ UserFunctions.cs
โ”‚   โ”‚   โ”‚   โ””โ”€โ”€ ProductFunctions.cs
โ”‚   โ”‚   โ””โ”€โ”€ Program.cs
โ”‚   โ””โ”€โ”€ MyApp.Core/                   # Your business logic
โ”‚       โ””โ”€โ”€ Services/
โ”‚           โ””โ”€โ”€ UserService.cs
โ””โ”€โ”€ tests/
    โ””โ”€โ”€ MyApp.IntegrationTests/
        โ”œโ”€โ”€ UserFunctionsTests.cs
        โ””โ”€โ”€ ProductFunctionsTests.cs

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

This project is licensed under the MIT License - see the LICENSE file for details.

Acknowledgments

Inspired by ASP.NET Core's WebApplicationFactory<TEntryPoint> pattern for testing.

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.1 197 11/2/2025
1.0.0 165 11/2/2025