在哪里创建 HostBuilder 并避免“以下构造函数参数没有匹配的夹具数据”

Sea*_*y84 1 c# xunit .net-core

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

IHostBuilder我似乎无法使用's 的 .NET core 方法执行或引导单元测试CreateHostBuilder

当我调试任何单元测试时,它会停止执行并收到此错误:

以下构造函数参数没有匹配的装置数据: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);
    }
}
Run Code Online (Sandbox Code Playgroud)

基类(我感觉这是创建主机构建器的错误方法):

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();
            });
}
Run Code Online (Sandbox Code Playgroud)

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

Moh*_*our 7

通过小的修改,您可以摆脱向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();
            });
}
Run Code Online (Sandbox Code Playgroud)

还有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);
    }
}
Run Code Online (Sandbox Code Playgroud)