如何在 .net6 中使用 WebApplicationFactory(没有可说话的入口点)
How to use WebApplicationFactory in .net6 (without speakable entry point)
在ASP.NET中,Core 6默认模板将Sturtup.cs
中的所有内容移动到Program.cs
中,并在Program.cs中使用顶级语句,所以没有更多(可说的) Program
class 以太币。
这看起来很棒,但现在,我需要测试所有这些。 WebApplicationFactory<T>
仍然希望我通过入口点-class,但我不能这样做(因为它的名字现在无法表达)。
如何在 ASP.NET Core 6 中配置集成测试?
问题已在 ASP.NET Core RC1 上解决,但截至目前(2021 年 9 月 20 日)文档尚不完整。
编译器在后台生成一个 Program
class 可以与 WebApplicationFactory<>
一起使用。 class 不是 public,所以应该使用 InternalsVisibleTo
项目设置。
Damien Edwards' Minimal API sample uses the latest nightly bits。测试网络应用 class 声明为:
internal class PlaygroundApplication : WebApplicationFactory<Program>
{
private readonly string _environment;
public PlaygroundApplication(string environment = "Development")
{
_environment = environment;
}
protected override IHost CreateHost(IHostBuilder builder)
{
...
在应用项目文件中,InternalsVisibleTo
用于使Program
class对测试项目可见:
<ItemGroup>
<InternalsVisibleTo Include="MinimalApiPlayground.Tests" />
</ItemGroup>
RC1 功能齐全,从以前的主要版本来看,它可能是第一个拥有 Go Live
许可证的版本,这意味着它在生产中得到支持。
请注意,如果您尝试使用 xUnit 及其 IClassFixture<T>
模式,如果您只使用 InternalsVisibleTo 方法,您将 运行 遇到问题。具体来说,你会得到这样的东西:
“不一致的可访问性:基本 class WebApplicationFactory<Program>
比 class CustomWebApplicationFactory
更难访问。”
当然,您可以通过将 CustomWebApplicationFactory
设置为内部来解决此问题,但它只会移动问题,因为现在您的单元测试 class 将给出相同的错误。当您尝试在那里更改它时,您会发现 xUnit 要求测试具有 public 构造函数(不是内部构造函数),您将被阻止。
避免所有这些并允许您仍然使用 IClassFixture<Program>
的解决方案是使 Program
class public。您显然可以通过删除 Program.cs 的魔术 no class 版本来做到这一点,但是如果您不想完全更改该文件,您可以只添加以下行:
public partial class Program { } // so you can reference it from tests
当然,一旦它 public 您就可以在您的测试项目中使用它,并且一切正常。
顺便说一句,您通常更喜欢使用 IClassFixture 的原因是它允许您在测试 class 构造函数中仅设置一次 WebApplicationFactory,并获取一个 HttpClient
实例您可以从中存储为一个字段。这允许您的所有测试更短,因为它们只需要引用客户端实例,而不是工厂。
示例:
public class HomePage_Get : IClassFixture<CustomWebApplicationFactory>
{
private readonly HttpClient _client = new HttpClient();
public HomePage_Get(CustomWebApplicationFactory factory)
{
_client = factory.CreateClient();
}
[Fact]
public async Task IncludesWelcome()
{
HttpResponseMessage response = await _client.GetAsync("/");
response.EnsureSuccessStatusCode();
string stringResponse = await response.Content.ReadAsStringAsync();
Assert.Contains("Welcome.", stringResponse);
}
}
最后注意Damian Edwards' MinimalAPIPlayground was updated to use this approach after we discussed the issue. See this commit
我试过了
<InternalsVisibleTo Include="MinimalApiPlayground.Tests" />
但是没有雪茄!删除它并添加部分 class 到 program.cs
#pragma warning disable CA1050 // Declare types in namespaces
public partial class Program
{
}
#pragma warning restore CA1050 // Declare types in namespaces
效果惊人。
在ASP.NET中,Core 6默认模板将Sturtup.cs
中的所有内容移动到Program.cs
中,并在Program.cs中使用顶级语句,所以没有更多(可说的) Program
class 以太币。
这看起来很棒,但现在,我需要测试所有这些。 WebApplicationFactory<T>
仍然希望我通过入口点-class,但我不能这样做(因为它的名字现在无法表达)。
如何在 ASP.NET Core 6 中配置集成测试?
问题已在 ASP.NET Core RC1 上解决,但截至目前(2021 年 9 月 20 日)文档尚不完整。
编译器在后台生成一个 Program
class 可以与 WebApplicationFactory<>
一起使用。 class 不是 public,所以应该使用 InternalsVisibleTo
项目设置。
Damien Edwards' Minimal API sample uses the latest nightly bits。测试网络应用 class 声明为:
internal class PlaygroundApplication : WebApplicationFactory<Program>
{
private readonly string _environment;
public PlaygroundApplication(string environment = "Development")
{
_environment = environment;
}
protected override IHost CreateHost(IHostBuilder builder)
{
...
在应用项目文件中,InternalsVisibleTo
用于使Program
class对测试项目可见:
<ItemGroup>
<InternalsVisibleTo Include="MinimalApiPlayground.Tests" />
</ItemGroup>
RC1 功能齐全,从以前的主要版本来看,它可能是第一个拥有 Go Live
许可证的版本,这意味着它在生产中得到支持。
请注意,如果您尝试使用 xUnit 及其 IClassFixture<T>
模式,如果您只使用 InternalsVisibleTo 方法,您将 运行 遇到问题。具体来说,你会得到这样的东西:
“不一致的可访问性:基本 class WebApplicationFactory<Program>
比 class CustomWebApplicationFactory
更难访问。”
当然,您可以通过将 CustomWebApplicationFactory
设置为内部来解决此问题,但它只会移动问题,因为现在您的单元测试 class 将给出相同的错误。当您尝试在那里更改它时,您会发现 xUnit 要求测试具有 public 构造函数(不是内部构造函数),您将被阻止。
避免所有这些并允许您仍然使用 IClassFixture<Program>
的解决方案是使 Program
class public。您显然可以通过删除 Program.cs 的魔术 no class 版本来做到这一点,但是如果您不想完全更改该文件,您可以只添加以下行:
public partial class Program { } // so you can reference it from tests
当然,一旦它 public 您就可以在您的测试项目中使用它,并且一切正常。
顺便说一句,您通常更喜欢使用 IClassFixture 的原因是它允许您在测试 class 构造函数中仅设置一次 WebApplicationFactory,并获取一个 HttpClient
实例您可以从中存储为一个字段。这允许您的所有测试更短,因为它们只需要引用客户端实例,而不是工厂。
示例:
public class HomePage_Get : IClassFixture<CustomWebApplicationFactory>
{
private readonly HttpClient _client = new HttpClient();
public HomePage_Get(CustomWebApplicationFactory factory)
{
_client = factory.CreateClient();
}
[Fact]
public async Task IncludesWelcome()
{
HttpResponseMessage response = await _client.GetAsync("/");
response.EnsureSuccessStatusCode();
string stringResponse = await response.Content.ReadAsStringAsync();
Assert.Contains("Welcome.", stringResponse);
}
}
最后注意Damian Edwards' MinimalAPIPlayground was updated to use this approach after we discussed the issue. See this commit
我试过了
<InternalsVisibleTo Include="MinimalApiPlayground.Tests" />
但是没有雪茄!删除它并添加部分 class 到 program.cs
#pragma warning disable CA1050 // Declare types in namespaces
public partial class Program
{
}
#pragma warning restore CA1050 // Declare types in namespaces
效果惊人。