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
The error happens due to this line in Program.cs:
I added this as I want to preserve
args
and therefore I usedWebApplication.CreateBuilder(args)
. Thanks to @davidfowl I used the following code snippet instead: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.I have came across the same issue when I tried to create .NET6 api as window service,
I solved with the below code
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 :