Skip to content

Support for Mocking and Integration Testing #668

@davidshaw2018

Description

@davidshaw2018

Hi, I'm trying to use Azure App Configuration for an ASP.NET minimal API web application, and was curious about how to properly implement mocking for app configuration.

It seems that builder.Configuration.AddAzureAppConfiguration eagerly connects to the specified configuration store instead of deferring connection until the Configuration is needed. This is the problem in integration testing, where the canonical method of creating a test server for integration tests still requires a valid AppConfiguration endpoint to connect to even if the service collection gets overriden in the SUT.

Are there any workarounds to this problem? I need to be able to run integration tests without connecting to a live appconfiguration instance, and I'd like to do so without cluttering my builder pipeline with branching if statements.

Providing a slimmed down version of my Program.cs and integration test server setup below.

// Program.cs
var builder = WebApplication.CreateBuilder(args);
builder.Configuration.AddAzureAppConfiguration(options =>
{
    options.Connect(new Uri("https://myconfigstore.azconfig.io"), new DefaultAzureCredential())
    .ConfigureRefresh(refreshOptions =>
        refreshOptions
        .Register(key: "SentinelKey", refreshAll: true))
    .UseFeatureFlags();
});

builder.Services.AddAzureAppConfiguration();
builder.Services.AddFeatureManagement();

var app = builder.Build();

app.UseAzureAppConfiguration();
app.Run();

public partial class Program { }

// IntegrationTest.cs

public class CustomWebAppFactory<TProgram> : WebApplicationFactory<TProgram> where TProgram : class
{
    protected override void ConfigureWebHost(IWebHostBuilder builder)
    {
        // Attempt to override the configuration
        builder.ConfigureAppConfiguration(config =>
        {
            config.AddInMemoryCollection(new Dictionary<string, string>
            {
                { "hello", "world" },
            });
        });
    }
}

public class Tests : IClassFixture<CustomWebAppFactory<Program>>
{
    private readonly CustomWebAppFactory<Program> _factory;
    public RandomTest(CustomWebAppFactory<Program> factory)
    {
        _factory = factory;
    }

    [Fact]
    public async Task Test1()
    {
        var client = _factory.CreateClient();
        var response = await client.GetAsync("/hello"); 
        response.EnsureSuccessStatusCode();
    }
}

I'd like that the test fixture never attempts to connect to AppCOnfiguration, but empirically I do see System.TimeoutException as the endpoint is not set.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions