gpt4 book ai didi

c# - 如何覆盖在某些测试中使用 IWebHostBuilder.ConfigureTestServices 模拟的服务

转载 作者:行者123 更新时间:2023-12-05 07:17:56 26 4
gpt4 key购买 nike

我有一个自定义 WebApplicationFactory<Startup>为此,我模拟了一些用于集成测试的服务,比如 DatabaseSeeder为了使测试运行得更快。

现在我想测试数据库播种器,所以我想覆盖配置以在这次测试中使用真正的数据库播种器。

我尝试使用 WithWebHostBuilder , 它返回一个新的 WebApplicationFactory<Startup>但是 builder.ConfigureTestServices这个新工厂中的方法在原始工厂之前运行,因此它被原始工厂覆盖 ConfigureTestServices

  /// <summary>
/// custom web application factory for testing.
/// </summary>
public class LwtTestWebApplicationFactory : WebApplicationFactory<Startup>
{
....

/// <inheritdoc />
protected override void ConfigureWebHost(IWebHostBuilder builder)
{
builder.ConfigureTestServices(
services =>
{
// Replace database seeder.
ServiceDescriptor databaseSeederDescriptor =
services.Single(s => s.ServiceType == typeof(IDatabaseSeeder));

services.Remove(databaseSeederDescriptor);

var mock = new Mock<IDatabaseSeeder>();
mock.Setup(s => s.SeedData())
.Returns(Task.CompletedTask);
services.AddTransient(resolver => mock.Object);

// Replace index creator.
ServiceDescriptor indexCreatorDescriptor =
services.Single(s => s.ServiceType == typeof(IIndexCreator));

services.Remove(indexCreatorDescriptor);

var indexCreatorMock = new Mock<IIndexCreator>();
indexCreatorMock.Setup(s => s.CreateIndexesAsync())
.Returns(Task.CompletedTask);
services.AddTransient(resolver => indexCreatorMock.Object);

// Remove the app's ApplicationDbContext registration.
ServiceDescriptor descriptor = services.SingleOrDefault(
d => d.ServiceType == typeof(DbContextOptions<IdentityDbContext>));

if (descriptor != null)
{
services.Remove(descriptor);
}

// Add ApplicationDbContext using an in-memory database for testing.
services.AddDbContext<IdentityDbContext>(
(options, context) => { context.UseInMemoryDatabase("InMemoryDbForTesting"); });

ServiceDescriptor appSettingDescriptor = services.SingleOrDefault(
d => d.ServiceType == typeof(AppSettings));

if (appSettingDescriptor != null)
{
var appSetting = (AppSettings)appSettingDescriptor.ImplementationInstance;
services.Remove(appSettingDescriptor);
services.AddSingleton(
new AppSettings
{
MongoDatabase = appSetting.MongoDatabase,
Secret = appSetting.Secret,
MongoConnectionString = this.mongoDbRunner.ConnectionString,
});
}
});
}

.....
}
}

我尝试了什么。

    using (var factory = new LwtTestWebApplicationFactory())
using (WebApplicationFactory<Startup> seedEnabledFactory = factory.WithWebHostBuilder(
builder =>
{
builder.ConfigureTestServices(
services =>
{
// Replace database seeder.
ServiceDescriptor databaseSeederDescriptor =
services.Single(s => s.ServiceType == typeof(IDatabaseSeeder));

services.Remove(databaseSeederDescriptor);

services.AddTransient<IDatabaseSeeder, DatabaseSeeder>();

// Replace index creator.
ServiceDescriptor indexCreatorDescriptor =
services.Single(s => s.ServiceType == typeof(IIndexCreator));

services.Remove(indexCreatorDescriptor);

services.AddTransient<IIndexCreator, MongoDbIndexCreator>();
});
}))

最佳答案

我有同样的任务 - 在测试方法中理想地在本地覆盖一些服务,而不是每次都重建容器:

[Fact]
public async Task GetSampleValue_WhenCalledWithMock_ReturnsMockValue()
{
using var mockServiceScope = _testHostServiceProvider.CreateScope(mockServices =>
{
var mockSampleService = Substitute.For<ISampleService>();
mockSampleService.GetSampleValue().ReturnsForAnyArgs("Mock value");
mockServices.AddSingleton(_ => mockSampleService);
});
var sampleController = RestClient.For<ISampleController>(_testHost.HttpClient);

var sampleValue = await sampleController.GetSampleValue();
Assert.Equal("Mock value", sampleValue);
}

我在库中实现了这个功能 Rsi.DependencyInjection .也许,它会对您有所帮助。

关于c# - 如何覆盖在某些测试中使用 IWebHostBuilder.ConfigureTestServices 模拟的服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58576638/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com