ASP.Net 6自定义WebApplicationFactory抛出异常

Kok*_*Teh 10 c# asp.net integration-testing asp.net-web-api asp.net-core

我正在将现有的 ASP.Net 5 Web 应用程序迁移到 ASP.Net 6,并遇到了通过集成测试的最后障碍。

\n

我自定义 WebApplicationFactory 并抛出异常:Changing the host configuration using WebApplicationBuilder.WebHost is not supported. Use WebApplication.CreateBuilder(WebApplicationOptions) instead.

\n
    public class CustomWebApplicationFactory<TStartup> : WebApplicationFactory<TStartup> where TStartup : class\n    {\n        protected override void ConfigureWebHost(IWebHostBuilder builder)\n        {\n            Environment.SetEnvironmentVariable("ASPNETCORE_ENVIRONMENT", "IntegrationTests");\n            builder.ConfigureServices(services => {\n                // Create a new service provider.\n                var serviceProvider = new ServiceCollection()\n                    .AddEntityFrameworkInMemoryDatabase().AddLogging()\n                    .BuildServiceProvider();\n\n                // Add a database context (AppDbContext) using an in-memory database for testing.\n                services.AddDbContextPool<AppDbContext>(options =>\n                {\n                    options.UseInMemoryDatabase("InMemoryAppDb");\n                    options.UseInternalServiceProvider(serviceProvider);\n                    options.EnableSensitiveDataLogging();\n                    options.EnableDetailedErrors();\n                    options.LogTo(Console.WriteLine);\n                });\n\n                services.AddDbContextPool<AppIdentityDbContext>(options =>\n                {\n                    options.UseInMemoryDatabase("InMemoryIdentityDb");\n                    options.UseInternalServiceProvider(serviceProvider);\n                    options.EnableSensitiveDataLogging();\n                    options.EnableDetailedErrors();\n                    options.LogTo(Console.WriteLine);\n                });\n                services.AddScoped<SignInManager<AppUser>>();\n                services.AddScoped<ILogger<UserRepository>>(provider => {\n                    ILoggerFactory loggerFactory = provider.GetRequiredService<ILoggerFactory>();\n                    return loggerFactory.CreateLogger<UserRepository>();\n                });\n                services.AddDistributedMemoryCache();\n                // Build the service provider.\n                var sp = services.BuildServiceProvider();\n\n                // Create a scope to obtain a reference to the database contexts\n                using (var scope = sp.CreateScope())\n                {\n                    var scopedServices = scope.ServiceProvider;\n                    var appDb = scopedServices.GetRequiredService<AppDbContext>();\n                    var identityDb = scopedServices.GetRequiredService<AppIdentityDbContext>();\n                    var logger = scopedServices.GetRequiredService<ILogger<CustomWebApplicationFactory<TStartup>>>();\n\n                    // Ensure the database is created.\n                    appDb.Database.EnsureCreated();\n                    identityDb.Database.EnsureCreated();\n\n                    try\n                    {\n                        // Seed the database with test data.\n                        SeedData.PopulateTestData(identityDb);\n                        SeedData.PopulateTestData(appDb);\n                    }\n                    catch (Exception ex)\n                    {\n                        logger.LogError(ex, $"An error occurred seeding the " +\n                            $"database with test messages. Error: {ex.Message}");\n                    }\n                }\n            });\n        }\n    }\n
Run Code Online (Sandbox Code Playgroud)\n

例外:

\n
  Message:\xe2\x80\x89\n    System.NotSupportedException : The content root changed from "C:\\Projects\\C#\\AspNetCoreApi\\src\\Web.Api\\" to "C:\\Projects\\C#\\AspNetCoreApi\\test\\Web.Api.IntegrationTests\\bin\\Debug\\net6.0\\". Changing the host configuration using WebApplicationBuilder.WebHost is not supported. Use WebApplication.CreateBuilder(WebApplicationOptions) instead.\n\n  Stack Trace:\xe2\x80\x89\n    ConfigureWebHostBuilder.UseSetting(String key, String value)\n    HostingAbstractionsWebHostBuilderExtensions.UseContentRoot(IWebHostBuilder hostBuilder, String contentRoot)\n    Program.<Main>$(String[] args)\xe2\x80\x89line\xe2\x80\x8958\n    --- End of stack trace from previous location ---\n    HostingListener.CreateHost()\n    <>c__DisplayClass8_0.<ResolveHostFactory>b__0(String[] args)\n    DeferredHostBuilder.Build()\n    WebApplicationFactory`1.CreateHost(IHostBuilder builder)\n    WebApplicationFactory`1.ConfigureHostBuilder(IHostBuilder hostBuilder)\n    WebApplicationFactory`1.EnsureServer()\n    WebApplicationFactory`1.CreateDefaultClient(DelegatingHandler[] handlers)\n    WebApplicationFactory`1.CreateDefaultClient(Uri baseAddress, DelegatingHandler[] handlers)\n    WebApplicationFactory`1.CreateClient(WebApplicationFactoryClientOptions options)\n    WebApplicationFactory`1.CreateClient()\n    MyControllerIntegrationTests.ctor(CustomWebApplicationFactory`1 factory)\xe2\x80\x89line\xe2\x80\x8915\n
Run Code Online (Sandbox Code Playgroud)\n

任何建议和见解都值得赞赏。

\n

Kok*_*Teh 9

由于 Program.cs 中的这一行而发生错误:

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

我添加这个是因为我想保留args,因此我使用了WebApplication.CreateBuilder(args). 感谢@davidfowl,我使用了以下代码片段:

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

并删除了有问题的代码行。请注意,builder.WebHost.UseContentRoot只要输入参数与默认值不同,就会抛出异常。就我而言,每当运行集成测试时它都会引发异常,但在正确运行应用程序时不会引发异常。

  • 这为我解决了另一个问题,当我将 .NET 6 应用程序部署到 Azure Web App 时,我会收到“DirectoryNotFoundException”(由于某种我仍然不明白的原因,它查看了 D 驱动器)。非常感谢您为这个令人头痛的问题提供了解决方案 (2认同)

Sad*_*yed 6

当我尝试创建 .NET6 api 作为窗口服务时,我遇到了同样的问题,

我用下面的代码解决了

  var builder = WebApplication.CreateBuilder(new WebApplicationOptions
      {
        Args = args,
        ContentRootPath = WindowsServiceHelpers.IsWindowsService() ? AppContext.BaseDirectory : default
      });
Run Code Online (Sandbox Code Playgroud)