'How to use AddInMemoryCollection in a .NET 6 integration test?

There is documentation about how to develop integration tests for .NET 6 . Logically, I want to mock external dependencies (typically urls refering to some external systems instead of a WireMock server) by changing configuration parameters. This can can be done with a method named AddInMemoryCollection . I have been using this when developing integration tests for .NET 5. But for .NET 6 applications (typically the ones without a Startup class) I did not succeed in this.

The problem is that I need to find a way to call CreateClient and then make sure AddInMemoryCollection is called before the Program.cs code is called in order to modify the configuration paramters before using them. How do I do this? How to properly use AddInMemoryCollection in a .NET 6 integration test?

Here is an example of something that does not work. AddInmemoryCollection does not modify the appsettings value.With .NET 5 such code works (but then I just refer to Startup).

    [Fact]
    public void ActualTest()
    {
        TryAddInMemoryCollection("http://localhost:1234");
    }

    private void TryAddInMemoryCollection(string urlOnLocalhost)
    {
        var factory = new IntegrationWebApplicationFactory<Program>();
        factory.WithWebHostBuilder(whb =>
        {
            whb.ConfigureAppConfiguration((context, configbuilder) =>
            {
                configbuilder.AddInMemoryCollection(new Dictionary<string, string>()
                 {
                     { "Google",urlOnLocalhost }
                 });
            });
        }).CreateClient();
    }

In my Program.cs

var googleLocation = builder.Configuration["Google"];
Console.WriteLine($"GOOGLELOCATION!! {googleLocation}");


Solution 1:[1]

https://github.com/dotnet/aspnetcore/issues/37680

As of right now this is not possible with .net 6. If you stick with minimal api / no startup.cs you need to be careful to register every service lazily and not instanziate anything that depends on configuration. Your test configuration will only get added once your entier Program.cs has executed.

There is nothing stopping you from using a Startup.cs in .net 6. Then this is not an issue at all. May or may not get fixed in .net 7. We donĀ“t know, yet.

Solution 2:[2]

You can do this:

[Fact]
public void ActualTest()
{
    TryAddInMemoryCollection("http://localhost:1234");
}

private void TryAddInMemoryCollection(string urlOnLocalhost)
{
    var factory = new IntegrationWebApplicationFactory<Program>();
    factory.WithWebHostBuilder(whb =>
    {
       whb.UseSetting("Google",urlOnLocalhost);
    }).CreateClient();
}

You may also add an extension method that accepts a dictionary:

public static IWebHostBuilder UseSetting(this IWebHostBuilder builder, IDictionary<string, string> settings)
{
    foreach (var (key, value) in settings)
    {
        builder.UseSetting(key, value);
    }
    return builder;
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Max
Solution 2 Peter Csala