【问题标题】:ASP.NET Core Testing - No method 'public static IHostBuilder CreateHostBuilder(string[] args)ASP.NET Core 测试 - 没有方法'public static IHostBuilder CreateHostBuilder(string[] args)
【发布时间】:2020-04-11 15:18:32
【问题描述】:

我正在尝试在测试中设置我的应用程序并在Startup's Configure 方法context.Database.EnsureCreated() 中使用并期望Sqlite 文件出现在Test's bin 文件夹中

这是我的代码:

using Microsoft.AspNetCore.Mvc.Testing;
using System.Threading.Tasks;
using Xunit;

namespace MyApp.Tests
{
    public class UnitTest1 : IClassFixture<CustomWebApplicationFactory<FakeStartup>>
    {
        private readonly CustomWebApplicationFactory<FakeStartup> _factory;

        public UnitTest1(CustomWebApplicationFactory<FakeStartup> factory)
        {
            _factory = factory;
        }

        [Fact]
        public async Task Test1()
        {
            // Arrange
            var client = _factory.CreateClient();

            // Act
            var response = await client.GetAsync("https://localhost:5001/");

            // Assert
            response.EnsureSuccessStatusCode(); // Status Code 200-299
            Assert.Equal("text/html; charset=utf-8", response.Content.Headers.ContentType.ToString());
        }
    }
}

哪个正在使用 WebAppFactory:

using MyApp.Tests;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc.Testing;

public class CustomWebApplicationFactory<TStartup> : WebApplicationFactory<TStartup> where TStartup : class
{
    protected override void ConfigureWebHost(IWebHostBuilder builder)
    {
        builder.UseStartup<FakeStartup>();
    }
}

FakeStartup 在哪里:

using MyApp.Database;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using System;

namespace MyApp.Tests
{
    public class FakeStartup
    {
        public FakeStartup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        public void ConfigureServices(IServiceCollection services)
        {            
            services.AddControllers();

            services.AddDbContext<Context>(x => x.UseSqlite($"filename={Guid.NewGuid():N}.db"));

            services.AddSwaggerGen(c =>
            {
                c.SwaggerDoc("v1", new OpenApiInfo { Title = "Test API", Version = "v1" });
            });
        }
    }

    public static void Configure(IApplicationBuilder app, IWebHostEnvironment env, Context context)
    {
        context.Database.EnsureDeleted();
        context.Database.EnsureCreated();

        app.UseSwagger();
        app.UseSwaggerUI(c =>
        {
            c.SwaggerEndpoint("/swagger/v1/swagger.json", "Test API v1");
            c.RoutePrefix = string.Empty;
        });

        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        app.UseForwardedHeaders(new ForwardedHeadersOptions
        {
            ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
        });

        app.UseAuthentication();

        app.UseCors(x =>
        {
            x.AllowAnyOrigin();
            x.AllowAnyMethod();
            x.AllowAnyHeader();
        });

        app.UseHttpsRedirection();

        app.UseRouting();

        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers();
        });
    }
}

问题来了

  Message: 
    System.InvalidOperationException : No method 'public static IHostBuilder CreateHostBuilder(string[] args)' or 'public static IWebHostBuilder CreateWebHostBuilder(string[] args)' found on 'AutoGeneratedProgram'. Alternatively, WebApplicationFactory`1 can be extended and 'CreateHostBuilder' or 'CreateWebHostBuilder' can be overridden to provide your own instance.
  Stack Trace: 
    WebApplicationFactory`1.CreateWebHostBuilder()
    WebApplicationFactory`1.EnsureServer()
    WebApplicationFactory`1.CreateDefaultClient(DelegatingHandler[] handlers)
    WebApplicationFactory`1.CreateDefaultClient(Uri baseAddress, DelegatingHandler[] handlers)
    WebApplicationFactory`1.CreateClient(WebApplicationFactoryClientOptions options)
    WebApplicationFactory`1.CreateClient()
    UnitTest1.Test1() line 20
    --- End of stack trace from previous location where exception was thrown

这可能是什么原因造成的?提前致谢

【问题讨论】:

    标签: c# asp.net-core testing


    【解决方案1】:

    解决方案:

    以这种方式创建CustomWebApplicationFactory

    public class CustomWebApplicationFactory<TStartup> : WebApplicationFactory<TStartup> where TStartup : class
    {
        protected override IHostBuilder CreateHostBuilder()
        {
            var builder = Host.CreateDefaultBuilder()
                              .ConfigureWebHostDefaults(x =>
                              {
                                  x.UseStartup<FakeStartup>().UseTestServer();
                              });
            return builder;
        }
    }
    

    在这里找到:

    https://thecodebuzz.com/no-method-public-static-ihostbuilder-createhostbuilder/

    【讨论】:

    • UseTestServer() 在 dotnet core 3.1 中不受支持(据我所知)。您有适用于 .net core 3.1 的解决方案吗?
    • @PMO1948 我在 .NET 5 上使用它,所以我很惊讶它不是 .NET Core 3.1 的一部分。
    • 嘿,这实际上是我的错误 - 我试图将 2.2 版本与 3.1 一起使用,这就是为什么它不起作用
    • 如果您在这里使用 dotnet 6.0,请查看 this answer
    • 嗨,我对这个解决方案有疑问。我的 sln 文件在一个文件夹中,项目在“src”子文件夹中。创建 WebApplicationFactory 时,它会尝试在 SLN 文件的同一目录中查找 My.Test.Folder。在不创建空文件夹的情况下如何解决?
    猜你喜欢
    • 1970-01-01
    • 2016-05-22
    • 2016-07-14
    • 1970-01-01
    • 2012-08-10
    • 2014-10-07
    • 1970-01-01
    • 2013-03-01
    • 1970-01-01
    相关资源
    最近更新 更多