如何从 WebApplicationFactoryConfigureTestServices 访问配置?

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

我使用

WebApplicationFactory
设置了一些集成测试,但在覆盖
ConfigureTestServices
方法中的某些服务时遇到了问题。

这是我的

WebApplicationFactory
:

public class TestWebApplicationFactory: WebApplicationFactory<Program> 
{
    protected override void ConfigureWebHost(IWebHostBuilder builder)
    {
        builder.ConfigureTestServices(s =>
        {
                 // Here I would like to access IConfiguration              
                 var configuration = ....?

                 //and then use some values from configuration, while overriding others with some fixed test values             
                services.ConfigureMyService(new MyOptions           
                {
                    Option1 = config.Option1,
                    Option2 = "new-fixed-value",
                    ... other options           
                });
        });
    } 
}

这是我的生产启动:

public static class StartupExtensions
{
    public static void ConfigureServices(
        this IServiceCollection services,
        IConfiguration configuration,
        IWebHostEnvironment environment)
    {
        var config = configuration.Get<MyConfig>();
        services.AddSingleton(config);

        services.ConfigureMyService(new MyOptions
        {
            Option1 = config.Option1,
            Option2 = config.Option2,
            ... other options
        });
    }
}

public class MyOptions
{
        public string Option1{ get; set; }
        public string Option2{ get; set; }
}

我尝试覆盖的服务已添加到我无权访问的外部包中的 DI 中。

MyService
可见性是内部的,因此不能直接从
WebApplicationFactory
引用/覆盖它。覆盖它的唯一方法是再次调用
ConfigureMyService
方法:

// Defined in an external package I don't have access to. MyService visibility is Internal, so it cannot be referenced/overridden
private static void ConfigureMyService(this IServiceCollection services, MyOptions options)
{
    var someService = new MyService(options.Option1, options.Option2);
    
    services.AddSingleton<MyService>(someService);
}

我想我可以在

ConfigureTestServices
内部构建服务提供者并通过它获得
MyOptions
(
s.BuildServiceProvider().GetRequiredService<MyOptions >()
),但这绝对是一种气味,我想避免这种情况。

c# asp.net-core testing dependency-injection
1个回答
0
投票

您应该使用工厂方法延迟配置依赖项,而不是直接为其提供实例:

builder.ConfigureTestServices(services =>
{
    services.AddSingleton<IAmazonDynamoDB>(serviceProvider =>
    {
        var configuration = serviceProvider.GetRequiredService<MyOptions>();
        // Do your customization...
        return MyFakeDynamoClient(configuration);
    });
});
© www.soinside.com 2019 - 2024. All rights reserved.