使用通用的IHostBuilder将.Net Core集成TestServer

16

我已经使用.Net Core 3.0 preview 2更新了我的网站,并想要使用TestServer进行集成测试。在.Net Core 2.2中,我能够使用WebApplicationFactory<Startup>完成它。

由于WebHostBuilder即将被弃用(请参见(https://learn.microsoft.com/en-us/aspnet/core/migration/22-to-30?view=aspnetcore-2.2&tabs=visual-studio)获取更多详细信息),因此我想要跟进并实现新的通用HostBuilder。它很适合启动网站,但是当我启动我的集成测试时会崩溃。我知道WebApplicationFactory确实使用了WebHostBuilder,这就是为什么会崩溃,但我不知道该如何将其更改为通用HostBuilder

以下是我在.Net Core 2.2中使用的代码:

namespace CompX.FunctionalTest.Web.Factory
{
    public class CustomWebApplicationFactory<TStartup> : WebApplicationFactory<Startup>
    {
        protected override void ConfigureWebHost(IWebHostBuilder builder)
        {
            builder.ConfigureServices(services =>
            {
                // Create a new service provider.
                var serviceProvider = new ServiceCollection()
                    .AddEntityFrameworkInMemoryDatabase()
                    .BuildServiceProvider();

                // Add a database context (ApplicationDbContext) using an in-memory 
                // database for testing.
                services.AddDbContext<ApplicationDbContext>(options =>
                {
                    options.UseInMemoryDatabase("InMemoryDbForTesting");
                    options.UseInternalServiceProvider(serviceProvider);
                });

                services.AddDbContext<AppIdentityDbContext>(options =>
                {
                    options.UseInMemoryDatabase("Identity");
                    options.UseInternalServiceProvider(serviceProvider);
                });

                services.AddIdentity<ApplicationUser, IdentityRole>()
                        .AddEntityFrameworkStores<AppIdentityDbContext>()
                        .AddDefaultTokenProviders();

                // Build the service provider.
                var sp = services.BuildServiceProvider();

                // Create a scope to obtain a reference to the database
                // context (ApplicationDbContext).
                using (var scope = sp.CreateScope())
                {
                    var scopedServices = scope.ServiceProvider;
                    var db = scopedServices.GetRequiredService<ApplicationDbContext>();
                    var loggerFactory = scopedServices.GetRequiredService<ILoggerFactory>();

                    var logger = scopedServices.GetRequiredService<ILogger<CustomWebApplicationFactory<TStartup>>>();

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

                    try
                    {
                        // Seed the database with test data.
                        var userManager = scopedServices.GetRequiredService<UserManager<ApplicationUser>>();
                        AppIdentityDbContextSeed.SeedAsync(userManager).GetAwaiter().GetResult();
                    }
                    catch (Exception ex)
                    {
                        logger.LogError(ex, $"An error occurred seeding the database with test messages. Error: {ex.Message}");
                    }
                }
            });
        }
    }
}

我尝试使用来自 Microsoft.AspNetCore.TestHost 的 TestServers,但它需要 new WebHostBuilder() 作为参数。

我还尝试将其作为参数传递,但也没有成功:

Host.CreateDefaultBuilder(args)
    .ConfigureWebHostDefaults(webBuilder =>
    {
        webBuilder.UseStartup<Startup>();
    });

它找不到.ConfigureWebHostDefaults()函数。

有人在.NET Core 3.0中成功实现了测试服务器吗? 非常感谢!

PS:我对.NET Core有点陌生。

编辑:

这是我从所有尝试创建新服务器的方法中获得的错误: enter image description here

这是 program.cs

namespace CompX.Web
{
    public class Program
    {
        public static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                });
    }
}

这是我在 Github 上创建的问题: https://github.com/aspnet/AspNetCore/issues/7754


你能展示一下你的Program.cs文件吗? - Kalten
好的,我会在编辑中添加它。 - Fearware
测试工厂正在等待一个IWebHostBuilder,但您使用的是IHostBuilder。我不确定目前是否支持此操作,因为这些API正在发生许多更改。需要检查aspnet源代码... - Kalten
好的,谢谢。如果我在 Stack 上没有得到答案,我可能会直接去 aspnet core 的 Github 上询问他们是否已经添加了这个功能。 - Fearware
我快速检查了源代码,发现所有内容都使用了iwebhostbuilder版本。 https://github.com/aspnet/AspNetCore/blob/master/src/Hosting/TestHost/src/WebHostBuilderExtensions.cs - Kalten
谢谢提供链接。我会在3.0分支上开一个问题,并询问他们是否可以为通用HostBuilder添加此功能。如果他们能够实现或有人提出想法,我会将我的问题标记为“已回答”:)非常感谢Kalten! - Fearware
1个回答

5
我终于知道了如何在3.0中实现它。 以下是完整的解决方案步骤,希望对需要此解决方案的人有所帮助:
  1. 你需要至少有.Net Core 3.0.0-preview2,因为他们在此预览版中添加了IHostbuilderWebApplicationFactoryhttps://github.com/aspnet/AspNetCore/pull/6585)。你可以在这里找到它:https://dotnet.microsoft.com/download/dotnet-core/3.0

  2. 升级以下至少这些软件包到版本3.0.0(https://github.com/aspnet/AspNetCore/issues/3756https://github.com/aspnet/AspNetCore/issues/3755):

    • Microsoft.AspNetCore.App Version=3.0.0-preview-19075-0444
    • Microsoft.AspNetCore.Mvc.Testing Version= 3.0.0-preview-19075-0444
    • Microsoft.Extensions.Hosting Version=3.0.0-preview.19074.2
  3. 删除现已弃用的包,这些包现在包含在Microsoft.AspNetCore.App中:

    • Microsoft.AspNetCore Version=2.2.0
    • Microsoft.AspNetCore.CookiePolicy Version=2.2.0
    • Microsoft.AspNetCore.HttpsPolicy Version=2.2.0
    • Microsoft.AspNetCore.Identity Version=2.2.0
  4. 如果你在WebApplicationFactory<Startup>构造器中使用了services.AddIdentity,那么你需要将其删除。否则,你将会收到一个新的错误,指出你已经使用了Identity.Application,并且该错误似乎是新的WebApplicationFactory现在正在使用Startup.cs中的错误。

我没有做其他修改。 希望它对某些人有所帮助!

更新:

直到我不得不使用另一个集成C#文件(例如LoginTest.csManageTest.cs),它才能正常工作。问题是当我运行测试时,它会无限循环,直到我按下CTRL + C为止。之后,它会显示一个访问被拒绝的错误。

再一次,我需要从我的WebApplicationFactory中移除一些东西:种子:

            try
            {
                // Seed the database with test data.
                var userManager = scopedServices.GetRequiredService<UserManager<ApplicationUser>>();
                AppIdentityDbContextSeed.SeedAsync(userManager).GetAwaiter().GetResult();
            }
            catch (Exception ex)
            {
                logger.LogError(ex, $"An error occurred seeding the database with test messages. Error: {ex.Message}");
            }

看起来新的WebApplicationFactory试图为每个工厂重新创建用户管理器。 我用Guid.NewGuid()替换了我的种子用户帐户。

花了我一段时间才搞清楚。 希望这可以再次帮助某些人。


你在哪里可以找到 Microsoft.AspNetCore.App 版本3呢?我只能找到Microsoft.AspNetCore.App版本2.2.7。 https://www.nuget.org/packages/Microsoft.AspNetCore.App/ - Awaa
我猜你的意思是Microsoft.AspNetCore.App 2.2.7也应该被移除? - Awaa
你好,Microsoft.AspNetCore.App现已过时。在我使用预览2版本时它还没有过时。现在它是.Net Core SDK 3.0的一部分。以下是链接:https://learn.microsoft.com/en-us/aspnet/core/migration/22-to-30?view=aspnetcore-3.0&tabs=visual-studio在“删除过时的包引用”部分中,您只需要删除引用,除非您的项目SDK是Microsoft.NET.Sdk.Web(https://learn.microsoft.com/en-us/aspnet/core/migration/22-to-30?view=aspnetcore-3.0&tabs=visual-studio#framework-reference)。 - Fearware

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接