如何在.net6中使用WebApplicationFactory(没有可讲的入口点)

Мак*_*вой 45 integration-testing asp.net-web-api asp.net-core .net-6.0

在 ASP.NET Core 6 中,默认模板将所有内容从Startup.cs移至Program.cs,并使用 Program.cs 中的顶级语句,因此不再有(可说的)Program类 ether。

这看起来很棒,但现在,我需要测试这一切。WebApplicationFactory<T>仍然期望我通过入门级,但我不能这样做(因为它的名字现在难以形容)。

预计如何在 ASP.NET Core 6 中配置集成测试?

ssm*_*ith 36

请注意,如果您尝试使用 xUnit 及其IClassFixture<T>模式,并且仅使用 InternalsVisibleTo 方法,则会遇到问题。具体来说,你会得到这样的结果:

在此输入图像描述

“可访问性不一致:基类比类WebApplicationFactory<Program>更难访问CustomWebApplicationFactory。”

当然,您可以通过创建CustomWebApplicationFactory内部来解决此问题,但它只会解决问题,因为现在您的单元测试类将给出相同的错误。当您尝试在那里更改它时,您会发现 xUnit 要求测试具有公共构造函数(而不是内部构造函数),并且您将被阻止。

避免所有这些并允许您仍然使用的解决方案IClassFixture<Program>是将Program类公开。显然,您可以通过摆脱 Program.cs 的神奇无类版本来做到这一点,但如果您不想完全更改该文件,您可以添加以下行:

public partial class Program { } // so you can reference it from tests
Run Code Online (Sandbox Code Playgroud)

当然,一旦公开,您就可以在您的测试项目中使用它,并且一切正常。

顺便说一句,您通常更喜欢使用 IClassFixture 的原因是它允许您在测试类构造函数中仅设置一次 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);
    }
}
Run Code Online (Sandbox Code Playgroud)

最后请注意,在我们讨论该问题后,Damian Edwards 的 MinimalAPIPlayground已更新为使用此方法。查看此提交


Pan*_*vos 35

该问题已在 ASP.NET Core RC1 上解决,但截至目前(2021 年 9 月 20 日)文档还不完整。

编译器Program在后台生成一个可以与WebApplicationFactory<>. 但该类不是公开的,因此InternalsVisibleTo应使用项目设置。

Damien Edwards 的最小 API 示例使用最新的 nightly 位。测试 Web 应用程序类声明为:

internal class PlaygroundApplication : WebApplicationFactory<Program>
{
    private readonly string _environment;

    public PlaygroundApplication(string environment = "Development")
    {
        _environment = environment;
    }

    protected override IHost CreateHost(IHostBuilder builder)
    {
    ...
Run Code Online (Sandbox Code Playgroud)

在应用程序项目文件中,InternalsVisibleTo用于使Program类对测试项目可见:

  <ItemGroup>
    <InternalsVisibleTo Include="MinimalApiPlayground.Tests" />
  </ItemGroup>
Run Code Online (Sandbox Code Playgroud)

RC1 功能完整,从之前的主要版本来看,它可能是第一个拥有Go Live许可证的版本,这意味着它在生产中受到支持。