与 WebApplicationFactory 的集成测试因 IServiceProvider 的 ObjectDisposeException 失败

问题描述 投票:0回答:1

我有一个简单的健康检查测试,如下所示:

public class HealthCheckEndpointTests : IClassFixture<ItemsApplicationFactory>
{
    private readonly ItemsApplicationFactory _factory;

    public HealthCheckEndpointTests(ItemsApplicationFactory factory)
    {
        _factory = factory;
    }

    public async Task HealthCheck_Test()
    {
       // Arrange
       HttpClient httpClient = _factory.CreateClient();

       // Act 
       string response = await httpClient.GetStringAsync("/health/live");

       // Assert
       Assert.Equal("Healthy", response);
    }
}

我的 ItemsApplicationFactory 看起来像这样:

public class ItemsApplicationFactory : WebApplicationFactory<Program>
{
    protected override void ConfigureWebHost(IWebHostBuilder builder)
    {
        builder.ConfigureKestrel(options => options.AllowSynchronousIO = true);


        builder.ConfigureServices(services =>
        {
            // remove db context options if exists 
            var dbContextDescriptor = services.SingleOrDefault(d => d.ServiceType == typeof(DbContextOptions<ItemsDbContext>));
            if (dbContextDescriptor != null)
                services.Remove(dbContextDescriptor);

            var serviceCollection = new ServiceCollection()
                .AddEntityFrameworkInMemoryDatabase()
                .BuildServiceProvider();

            services.AddDbContext<ItemsDbContext>(mariaDb =>
            {
                mariaDb.UseInMemoryDatabase("template");
                mariaDb.UseInternalServiceProvider(serviceCollection);
            });
        });
    }
}

当我运行测试时,抛出以下异常

System.ObjectDisposedException : Cannot access a disposed object.
Object name: 'IServiceProvider'

我改变了我的测试,看看异常是否是由 ItemsApplicationFactory 或 HttpClient 的初始化引起的。所以测试看起来像这样

public class HealthCheckEndpointTests : IClassFixture<ItemsApplicationFactory>
{
    private readonly ItemsApplicationFactory _factory;

    public HealthCheckEndpointTests(ItemsApplicationFactory factory)
    {
        _factory = factory;
    }

    public async Task HealthCheck_Test()
    {
       // Arrange
       HttpClient httpClient = _factory.CreateClient();

       // Act 
       await Task.Run(() => Task.CompletedTask);

       // Assert
       Assert.True(true);
    }
}

测试没有抛出任何异常。

为什么

_factory.CreateClient();
不会抛出,而
httpClient.GetStringAsync("/health/live")
会抛出?以及如何解决这个问题?

c# asp.net-core asp.net-web-api integration-testing xunit
1个回答
0
投票

我也有同样的经历。一个可能的原因是测试执行中出现了一些失败,但您无法找出到底是什么,并且测试显示

IServiceProvider
已被处置。

这不是原因,而是结果。

转到您的

Program.cs
并将所有内容包在

try {
 //...
} catch(Exception exception) {
// breakpoint here to find out the real reason
}

并调试测试。您将看到导致您所看到的错误的真正原因。

在我的例子中,当 SSL 不受信任时,一个驱动程序试图连接到 CosmosDb,但它可以是任何东西。

© www.soinside.com 2019 - 2024. All rights reserved.