将ASP.NET测试启动类移到项目根目录之外?

时间:2019-07-03 21:11:32

标签: c# asp.net .net-core blazor

我有一个Blazor(ASP.NET Core 3.0)应用程序(默认模板),我想使用Selenium编写一些集成测试。为此,我需要在测试运行之前启动Web应用程序。

我通过运行

CreateHostBuilderWithStartup<Startup>(new string[0]).UseContentRoot(contentRoot).Build().RunAsync();

private static IHostBuilder CreateHostBuilderWithStartup<TStartup>(string[] args) where TStartup : class
    {
        return Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<TStartup>();
            });
    }

其中contentRoot是被测项目的路径。一切正常,服务器按预期运行。

我的解决方案包含2个项目-应用程序代码和测试代码。

但是,如果我尝试使用从启动(即CreateHostBuilderWithStartup<TestStartup>)继承的测试项目中获得的Startup类,则服务器会为每个请求返回500个内部服务器错误。服务器的控制台输出中的错误是:

Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware: Error: An unhandled exception has occurred while executing the request.

System.InvalidOperationException: Cannot find the fallback endpoint specified by route values: { page: /_Host, area:  }.
   at Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.DynamicPageEndpointMatcherPolicy.ApplyAsync(HttpContext httpContext, CandidateSet candidates)
   at Microsoft.AspNetCore.Routing.Matching.DfaMatcher.SelectEndpointWithPoliciesAsync(HttpContext httpContext, IEndpointSelectorPolicy[] policies, CandidateSet candidateSet)
   at Microsoft.AspNetCore.Routing.EndpointRoutingMiddleware.<Invoke>g__AwaitMatch|6_1(EndpointRoutingMiddleware middleware, HttpContext httpContext, Task matchTask)
   at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.<Invoke>g__Awaited|6_0(ExceptionHandlerMiddleware middleware, HttpContext context, Task task)
'dotnet.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App\3.0.0-preview6.19307.2\Microsoft.AspNetCore.Http.Extensions.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.

如果我将TestStartup移到主代码项目中,则可以正常工作,但理想情况下,我希望将测试代码保留在测试项目中。我需要使用此TestStartup类,以便可以重写ConfigureServices方法来更改注入的依赖项。

所以这个问题的核心是,我可以将Startup类放在我正在运行的ASP.NET Core项目的根目录之外吗?

对此将提供任何帮助!

2 个答案:

答案 0 :(得分:0)

经过大量的实验和研究,由于无法遵守使用ContentRoot方法设置的UseContentRoot路径的错误,目前似乎无法移动Startup类。 issue #11921在AspNetCore GitHub上跟踪了此错误。

如果需要能够从测试项目中注入依赖项,那么非常棘手的解决方法是在主项目中创建一个带有静态Dependencies字段的静态类Action<IStartupConfiguration> RegisterDependencies调用Startup类:

public void ConfigureServices(IServiceCollection services)
{
    services.AddRazorPages();
    services.AddServerSideBlazor();
    Dependencies.RegisterDependencies(services);
}

然后,在Program.cs中将RegisterDepenedencies设置为注册所需的依赖项:

public static void Main(string[] args)
{
    Dependencies.RegisterDependencies = s =>
    {
        s.AddSingleton<IWeatherForecastService, WeatherForecastService>();
    };

    CreateHostBuilder(args).Build().Run();
}

您现在可以在测试项目中更改此方法,以在运行集成测试时配置不同的依赖项。在您的测试项目中:

Dependencies.RegisterDependencies = s =>
{
    s.AddSingleton<IWeatherForecastService, MockWeatherForecastService>();
};

这非常棘手,希望解决ContentRoot问题,然后改为使用将内容根目录更改为主项目

答案 1 :(得分:0)

对我来说以下有效:

Program.CreateHostBuilder(new string[0]).Build().RunAsync();

虽然我必须创建一个 .sln,它将项目与测试文件夹绑定,如 this guide