我有一个简单的健康检查测试,如下所示:
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")
会抛出?以及如何解决这个问题?
我也有同样的经历。一个可能的原因是测试执行中出现了一些失败,但您无法找出到底是什么,并且测试显示
IServiceProvider
已被处置。
这不是原因,而是结果。
转到您的
Program.cs
并将所有内容包在下
try {
//...
} catch(Exception exception) {
// breakpoint here to find out the real reason
}
并调试测试。您将看到导致您所看到的错误的真正原因。
在我的例子中,当 SSL 不受信任时,一个驱动程序试图连接到 CosmosDb,但它可以是任何东西。