运行 ASP.NET Core 集成测试时出现下面的错误:
System.InvalidOperationException : No method 'public static IWebHostBuilder CreateWebHostBuilder(string[] args)' found on 'AutoGeneratedProgram'. Alternatively, WebApplicationFactory`1 can be extended and 'protected virtual IWebHostBuilder CreateWebHostBuilder()' can be overridden to provide your own IWebHostBuilder instance.
Stack Trace:
at Microsoft.AspNetCore.Mvc.Testing.WebApplicationFactory`1.CreateWebHostBuilder()
请问如何解决?
查看 WebApplicationFactory 的源代码 ,知道了异常是在下面的代码中抛出的
var builder = WebHostBuilderFactory.CreateFromTypesAssemblyEntryPoint<TEntryPoint>(Array.Empty<string>());
if (builder == null)
{
throw new InvalidOperationException(Resources.FormatMissingCreateWebHostBuilderMethod(
nameof(IWebHostBuilder),
typeof(TEntryPoint).Assembly.EntryPoint.DeclaringType.FullName,
typeof(WebApplicationFactory<TEntryPoint>).Name,
nameof(CreateWebHostBuilder)));
}
WebApplicationFactory<TEntryPoint>
默认是在 TEntryPoint
所在的程序集中寻找 Program
。出现上面的问题是由于 IClassFixture< WebApplicationFactory<TestStartup>>
中的 TestStartup 是在集成测试的项目中,不在所测试的 ASP.NET Core 项目中,如果将 TestStartup
改为 ASP.NET Core 项目中的 Startup
就没这个问题。
TestStartup
继承自 Startup
,我不想把 TestStartup 放到 ASP.NET Core 项目中,最终采取的解决方案如下:
public class UploadWebAppFactory<TStartup, TTestStartup> : WebApplicationFactory<TStartup>
where TStartup : class
where TTestStartup : class
{
protected override TestServer CreateServer(IWebHostBuilder builder)
{
builder.UseStartup<TTestStartup>();
return base.CreateServer(builder);
}
}
如果 TestStartup 没有继承 Startup ,需要采用下面的方法:
public class BlogAdminWebFactory : WebApplicationFactory<TestStartup>
{
protected override IWebHostBuilder CreateWebHostBuilder()
{
return WebHost.CreateDefaultBuilder()
.UseStartup<TestStartup>();
}
protected override void ConfigureWebHost(IWebHostBuilder builder)
{
builder.UseContentRoot(".");
base.ConfigureWebHost(builder);
}
}
对于 TestStartup 没有继承 Startup 的情况,发现了一个更简单的解决方法
public class BlogAdminWebFactory : WebApplicationFactory<Startup>
{
protected override IWebHostBuilder CreateWebHostBuilder()
{
return WebHost.CreateDefaultBuilder()
.UseStartup<TestStartup>();
}
}
检查一下program.com