Wou*_*ort 16 c# integration-testing asp.net-core
我有一个 ASP.NET Core 项目,其中包含一些简单的 Razor 页面和一个 Web API 控制器。
我使用Clean Architecture作为起点。我重命名了项目名称,删除了 MVC 内容并添加了一些我自己的代码。一切正常运行。
但是,集成测试在调用时会抛出以下错误factory.CreateClient():
Test Name: ToDo.Tests.Integration.Web.HomeControllerIndexShould.ReturnViewWithCorrectMessage
Test FullName: ToDo.Tests.Integration.Web.HomeControllerIndexShould.ReturnViewWithCorrectMessage
Test Source: C:\Source\Utopia\tests\ToDo.Tests\Integration\Web\HomeControllerIndexShould.cs : line 18
Test Outcome: Failed
Test Duration: 0:00:00,001
Result StackTrace:
at Microsoft.AspNetCore.Hosting.Internal.HostingEnvironmentExtensions.Initialize(IHostingEnvironment hostingEnvironment, String contentRootPath, WebHostOptions options)
at Microsoft.AspNetCore.Hosting.WebHostBuilder.BuildCommonServices(AggregateException& hostingStartupErrors)
at Microsoft.AspNetCore.Hosting.WebHostBuilder.Build()
at Microsoft.AspNetCore.TestHost.TestServer..ctor(IWebHostBuilder builder, IFeatureCollection featureCollection)
at Microsoft.AspNetCore.Mvc.Testing.WebApplicationFactory`1.CreateServer(IWebHostBuilder builder)
at Microsoft.AspNetCore.Mvc.Testing.WebApplicationFactory`1.EnsureServer()
at Microsoft.AspNetCore.Mvc.Testing.WebApplicationFactory`1.CreateDefaultClient(DelegatingHandler[] handlers)
at Microsoft.AspNetCore.Mvc.Testing.WebApplicationFactory`1.CreateClient(WebApplicationFactoryClientOptions options)
at ToDo.Tests.Integration.Web.HomeControllerIndexShould..ctor(CustomWebApplicationFactory`1 factory) in C:\Source\Utopia\tests\ToDo.Tests\Integration\Web\HomeControllerIndexShould.cs:line 14
Result Message:
System.ArgumentException : The content root 'C:\Source\Utopia\ToDo.Web' does not exist.
Parameter name: contentRootPath
Run Code Online (Sandbox Code Playgroud)
我尝试使用和配置自定义WebApplicationFactorybuilder.UseContentRoot,builder.UseSolutionRelativeContentRoot但无论我为这些ContentRoot方法使用什么值,它都会抛出相同的错误。
我不知道为什么我的测试失败,而 Clean Architecture 示例中的测试正在运行。我也不知道怎么修。
任何指针都非常感谢!
Kit*_*Kit 12
这个方法对我有用
var client = _factory
.WithWebHostBuilder(builder => builder.UseSolutionRelativeContentRoot("relative/path/of/project/under/test"))
.CreateClient();
Run Code Online (Sandbox Code Playgroud)
有关更多信息,请参阅测试基础架构如何推断应用内容根路径。
小智 10
我对这个问题的解决方案是WebApplicationFactory用 Application Startup定义但WebHostBuilder用 TestStartup设置。
例子:
public class MyApplicationFactory : WebApplicationFactory<Startup>
{
protected override IWebHostBuilder CreateWebHostBuilder()
{
return WebHost.CreateDefaultBuilder();
}
protected override void ConfigureWebHost(IWebHostBuilder builder)
{
builder.UseStartup<TestStartup>();
base.ConfigureWebHost(builder);
}
}
Run Code Online (Sandbox Code Playgroud)
似乎 WebApplicationFactory 应该使用真正的 Startup 类作为参数类型:
class TestWebApplicationFactory : WebApplicationFactory<Startup>
{
protected override IWebHostBuilder CreateWebHostBuilder()
{
return WebHost.CreateDefaultBuilder<TestableStartup>();
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,Startup 是真实 SUT 代码上的类型,而 TestableStartup 是 TestingStartup 配置。
如果您使用的是 ReSharper,它很可能与版本有关。我们发现了 2018.3 版本的问题。添加 UseSolutionRelativeContentRoot 解决了它。
protected override void ConfigureWebHost(IWebHostBuilder builder)
{
builder.UseKestrel()
.UseSolutionRelativeContentRoot("")
.ConfigureAppConfiguration((context, configBuilder) =>
{
// Config code
})
.UseStartup<Startup>();
}
Run Code Online (Sandbox Code Playgroud)
我不完全确定你在说什么,但你首先不应该在测试项目中配置这样的东西。相反,您应该创建一个类似TestStartupSUT 类的类并继承该类Startup。在 SUT 的Startup类中,您应该将数据库设置等内容分解为虚拟私有方法,然后您可以在TestStartup. 例如,您可以创建如下方法:
private virtual void ConfigureDatabase(IServiceCollection services)
{
services.AddDbContext<MyContext>(o =>
o.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
}
Run Code Online (Sandbox Code Playgroud)
然后在你的 中TestStartup,你可以添加类似的内容:
private override void ConfigureDatabase(IServiceCollection services)
{
var databaseName = Guid.NewGuid().ToString();
services.AddDbContext<MyContext>(o =>
o.UseInMemoryDatabase(databaseName));
}
Run Code Online (Sandbox Code Playgroud)
然后,在设置工厂进行测试时,您告诉它使用您的TestStartup:
var client = factory.WithWebHostBuilder(b => b.UseStartup<TestStartup>()).CreateClient();
Run Code Online (Sandbox Code Playgroud)
或者,您可以创建自己的自定义WebApplicationFactory并将其设置在那里:
public class CustomWebApplicationFactory<TStartup> : WebApplicationFactory<RazorPagesProject.Startup>
{
protected override void ConfigureWebHost(IWebHostBuilder builder)
{
builder.UseStartup<TestStartup>();
}
}
Run Code Online (Sandbox Code Playgroud)
请记住,TStartup泛型类型参数用于获取入口点程序集,因此您仍将其放在Startup那里。
这样做的要点是,您不需要重复所有启动配置,然后记住保持同步。您的测试客户端将使用与实际应用程序使用的完全相同的启动配置,除了一些保留替换(例如使用内存数据库)。
| 归档时间: |
|
| 查看次数: |
7709 次 |
| 最近记录: |