14

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

由于WebHostBuilder即将被弃用(有关更多详细信息,请参阅(https://docs.microsoft.com/en-us/aspnet/core/migration/22-to-30?view=aspnetcore-2.2&tabs=visual-studio)。 ),我现在想跟进并实施新的 Generic HostBuilder。它非常适合启动网站,但是当我启动我的集成测试时它崩溃了。我知道这WebApplicationFactory确实有用WebHostBuilder,这就是它崩溃的原因,但我不知道如何为 Generic 更改它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}");
                    }
                }
            });
        }
    }
}

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

我也尝试将其作为参数传递,但效果不佳:

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

它找不到.ConfigureWebHostDefaults()功能。

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

PS:我对.Net Core有点陌生

编辑 :

这是我从尝试创建新服务器的所有方法中得到的错误: 在此处输入图像描述

这里是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

4

1 回答 1

5

我终于知道如何在 3.0 中做到这一点。以下是有关如何为需要解决方案的任何人执行此操作的完整演练:

  1. 您至少需要.Net Core 3.0.0-preview2,因为他们在此预览版中添加了WebApplicationFactorywith ( https://github.com/aspnet/AspNetCore/pull/6585)。你可以在这里找到它:https ://dotnet.microsoft.com/download/dotnet-core/3.0IHostbuilder

  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. 如果您services.AddIdentityWebApplicationFactory<Startup>构建器中使用,则需要将其删除。否则,您将收到一个新错误,说明您已经将该方案用于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() 替换了我的种子用户帐户。

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

于 2019-02-23T01:37:10.073 回答