【问题标题】:Where to create HostBuilder and avoid 'The following constructor parameters did not have matching fixture data'在哪里创建 HostBuilder 并避免“以下构造函数参数没有匹配的夹具数据”
【发布时间】:2020-06-23 14:40:34
【问题描述】:

我采用了一个遗留的 .NET 框架应用程序,它只包含类库和一个单元测试项目,并将它们全部转换为 .NET core 3.1。

我似乎无法使用使用IHostBuilderCreateHostBuilder 的.NET 核心方法执行或引导单元测试。

当我调试我的任何单元测试时,它会停止执行并出现以下错误:

以下构造函数参数没有匹配的夹具数据:IOptions`1 appConfig、IServiceX serviceX、ITemplateEngine templateEngine 异常没有堆栈跟踪

示例单元测试:

public class TemplateGenerationTests : BaseTest
{
    private readonly AppConfiguration appConfig;
    private readonly IServiceX serviceX;
    private readonly ITemplateEngine templateEngine;

    public TemplateGenerationTests(IOptions<AppConfiguration> appConfig, IServiceX serviceX, ITemplateEngine templateEngine)
    {
        this.appConfig = appConfig.Value;
        this.serviceX = serviceX;
        this.templateEngine = templateEngine;
    }

    [Fact]
    public void SomeTestIhave()
    {
        //removed for brevity
        serviceX.DoWork(appConfig.SomeAppProp);
        

        Assert.NotNull(result);
        Assert.NotEmpty(result);
    }
}

基类(我感觉这是创建 hostbuiler 的错误方式):

public class BaseTest
{
    public BaseTest()
    {
        var builder = CreateHostBuilder();
        Task.Run(() => builder.RunConsoleAsync());
    }

    public static IHostBuilder CreateHostBuilder(string[] args = null) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureAppConfiguration((hostingContext, config) =>
            {
                config.AddJsonFile("appsettings.json", optional: true);
                config.AddEnvironmentVariables();

                if (args != null)
                {
                    config.AddCommandLine(args);
                }
            })
            .ConfigureServices((hostContext, services) =>
            {
                services.AddOptions();
                services.Configure<AppConfiguration>(hostContext.Configuration.GetSection("AppConfiguration"));
                
                services.AddTransient<IServiceX, ServiceX>();
                services.AddTransient<ITemplateEngine, TemplateEngine>();
                
                //removed for brevity..
            })
            .ConfigureLogging((hostingContext, logging) =>
            {
                logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
                logging.AddConsole();
            });
}

理想情况下,我正在寻找一个可以设置 HostBuilder 的点,即在控制台或 API .NET 项目中,这将在 Program 类的 Main 方法中。

【问题讨论】:

    标签: c# .net-core xunit


    【解决方案1】:

    通过小修改,您可以摆脱将服务注入TemplateGenerationTests 类:

    BaseTest 类:

    public class BaseTest
    {
        public BaseTest()
        {
            TestHost = CreateHostBuilder().Build();
            Task.Run(() => TestHost.RunAsync());
        }
    
        public IHost TestHost { get; }
    
        public static IHostBuilder CreateHostBuilder(string[] args = null) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureAppConfiguration((hostingContext, config) =>
                {
                    config.AddJsonFile("appsettings.json", optional: true);
                    config.AddEnvironmentVariables();
    
                    if (args != null)
                    {
                        config.AddCommandLine(args);
                    }
                })
                .ConfigureServices((hostContext, services) =>
                {
                    services.AddOptions();
                    services.Configure<AppConfiguration>(hostContext.Configuration.GetSection("AppConfiguration"));
    
                    services.AddTransient<IServiceX, ServiceX>();
                    services.AddTransient<ITemplateEngine, TemplateEngine>();
    
                    //removed for brevity..
                })
                .ConfigureLogging((hostingContext, logging) =>
                {
                    logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
                    logging.AddConsole();
                });
    }
    

    还有TemplateGenerationTests 类:

    public class TemplateGenerationTests : IClassFixture<BaseTest>
    {
        private readonly IHost _host;
    
        public TemplateGenerationTests(BaseTest baseTest)
        {
            _host = baseTest.TestHost;
        }
    
        [Fact]
        public void SomeTestIhave()
        {
            // Arrange
            var serviceX = _host.Services.GetService<IServiceX>();
            var appConfig = _host.Services.GetService<AppConfiguration>();
    
            // Act
            var result = serviceX.DoWork(appConfig.SomeAppProp);
    
            // Assert
            Assert.NotNull(serviceX);
            Assert.NotEmpty(result);
        }
    }
    

    【讨论】:

    • 除一部分外,此功能正常,appConfig 未解析且为空。
    • 检查此行结果不为空hostContext.Configuration.GetSection("AppConfiguration")
    • 是的,那是返回一个空值。谢谢
    猜你喜欢
    • 2018-12-11
    • 1970-01-01
    • 1970-01-01
    • 2019-11-07
    • 2020-11-02
    • 1970-01-01
    • 2021-11-30
    • 2010-09-21
    • 1970-01-01
    相关资源
    最近更新 更多