skip to Main Content

I am migrating my existing ASP.Net 5 web app to ASP.Net 6 and bump into the final hurdles of getting the integration tests to pass.

I customize WebApplicationFactory and it throws exception: Changing the host configuration using WebApplicationBuilder.WebHost is not supported. Use WebApplication.CreateBuilder(WebApplicationOptions) instead.

    public class CustomWebApplicationFactory<TStartup> : WebApplicationFactory<TStartup> where TStartup : class
    {
        protected override void ConfigureWebHost(IWebHostBuilder builder)
        {
            Environment.SetEnvironmentVariable("ASPNETCORE_ENVIRONMENT", "IntegrationTests");
            builder.ConfigureServices(services => {
                // Create a new service provider.
                var serviceProvider = new ServiceCollection()
                    .AddEntityFrameworkInMemoryDatabase().AddLogging()
                    .BuildServiceProvider();

                // Add a database context (AppDbContext) using an in-memory database for testing.
                services.AddDbContextPool<AppDbContext>(options =>
                {
                    options.UseInMemoryDatabase("InMemoryAppDb");
                    options.UseInternalServiceProvider(serviceProvider);
                    options.EnableSensitiveDataLogging();
                    options.EnableDetailedErrors();
                    options.LogTo(Console.WriteLine);
                });

                services.AddDbContextPool<AppIdentityDbContext>(options =>
                {
                    options.UseInMemoryDatabase("InMemoryIdentityDb");
                    options.UseInternalServiceProvider(serviceProvider);
                    options.EnableSensitiveDataLogging();
                    options.EnableDetailedErrors();
                    options.LogTo(Console.WriteLine);
                });
                services.AddScoped<SignInManager<AppUser>>();
                services.AddScoped<ILogger<UserRepository>>(provider => {
                    ILoggerFactory loggerFactory = provider.GetRequiredService<ILoggerFactory>();
                    return loggerFactory.CreateLogger<UserRepository>();
                });
                services.AddDistributedMemoryCache();
                // Build the service provider.
                var sp = services.BuildServiceProvider();

                // Create a scope to obtain a reference to the database contexts
                using (var scope = sp.CreateScope())
                {
                    var scopedServices = scope.ServiceProvider;
                    var appDb = scopedServices.GetRequiredService<AppDbContext>();
                    var identityDb = scopedServices.GetRequiredService<AppIdentityDbContext>();
                    var logger = scopedServices.GetRequiredService<ILogger<CustomWebApplicationFactory<TStartup>>>();

                    // Ensure the database is created.
                    appDb.Database.EnsureCreated();
                    identityDb.Database.EnsureCreated();

                    try
                    {
                        // Seed the database with test data.
                        SeedData.PopulateTestData(identityDb);
                        SeedData.PopulateTestData(appDb);
                    }
                    catch (Exception ex)
                    {
                        logger.LogError(ex, $"An error occurred seeding the " +
                            $"database with test messages. Error: {ex.Message}");
                    }
                }
            });
        }
    }

Exception:

  Message: 
    System.NotSupportedException : The content root changed from "C:ProjectsC#AspNetCoreApisrcWeb.Api" to "C:ProjectsC#AspNetCoreApitestWeb.Api.IntegrationTestsbinDebugnet6.0". Changing the host configuration using WebApplicationBuilder.WebHost is not supported. Use WebApplication.CreateBuilder(WebApplicationOptions) instead.

  Stack Trace: 
    ConfigureWebHostBuilder.UseSetting(String key, String value)
    HostingAbstractionsWebHostBuilderExtensions.UseContentRoot(IWebHostBuilder hostBuilder, String contentRoot)
    Program.<Main>$(String[] args) line 58
    --- End of stack trace from previous location ---
    HostingListener.CreateHost()
    <>c__DisplayClass8_0.<ResolveHostFactory>b__0(String[] args)
    DeferredHostBuilder.Build()
    WebApplicationFactory`1.CreateHost(IHostBuilder builder)
    WebApplicationFactory`1.ConfigureHostBuilder(IHostBuilder hostBuilder)
    WebApplicationFactory`1.EnsureServer()
    WebApplicationFactory`1.CreateDefaultClient(DelegatingHandler[] handlers)
    WebApplicationFactory`1.CreateDefaultClient(Uri baseAddress, DelegatingHandler[] handlers)
    WebApplicationFactory`1.CreateClient(WebApplicationFactoryClientOptions options)
    WebApplicationFactory`1.CreateClient()
    MyControllerIntegrationTests.ctor(CustomWebApplicationFactory`1 factory) line 15

Any advice and insight is appreciated.

3

Answers


  1. Chosen as BEST ANSWER

    The error happens due to this line in Program.cs:

    builder.WebHost.UseContentRoot(Path.GetFullPath(Directory.GetCurrentDirectory())); // Changing the host configuration using WebApplicationBuilder.Host is not supported. Use WebApplication.CreateBuilder(WebApplicationOptions) instead.
    

    I added this as I want to preserve args and therefore I used WebApplication.CreateBuilder(args). Thanks to @davidfowl I used the following code snippet instead:

    var builder = WebApplication.CreateBuilder(new WebApplicationOptions
    {
        ApplicationName = typeof(Program).Assembly.FullName,
        ContentRootPath = Path.GetFullPath(Directory.GetCurrentDirectory()),
        WebRootPath = "wwwroot",
        Args = args
    });
    

    and removed the faulting line of code. Note that builder.WebHost.UseContentRoot will throw exception whenever the input parameter differs from the default value. In my case, it throws exception whenever running the integration tests but NOT when running the application proper.


  2. I have came across the same issue when I tried to create .NET6 api as window service,

    I solved with the below code

      var builder = WebApplication.CreateBuilder(new WebApplicationOptions
          {
            Args = args,
            ContentRootPath = WindowsServiceHelpers.IsWindowsService() ? AppContext.BaseDirectory : default
          });
    
    Login or Signup to reply.
  3. I have the same issue in my integration test, when I have migrated the API to .NET6.

    I solved this just by adding builder.UseContentRoot(".") in my customWebApplicationFactory.

    The whole code :

    public class CustomWebApplicationFactoryWithMock<TStartup> : WebApplicationFactory<TStartup> where TStartup : class
    {
        protected override void ConfigureWebHost(IWebHostBuilder builder)
        {
            builder.UseContentRoot(".");
    
            builder.ConfigureServices(services =>
            {
                services.AddScoped<TService, TImpementation>();
            });
        }
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search