【问题标题】:Move ASP.NET test Startup class outside of project root directory?将 ASP.NET 测试启动类移到项目根目录之外?
【发布时间】:2019-11-14 14:35:01
【问题描述】:

我有一个 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 个项目 - 应用程序代码和测试代码。

但是,如果我尝试使用继承自启动的测试项目中的 Startup 类(即CreateHostBuilderWithStartup&lt;TestStartup&gt;),则服务器会为每个请求返回 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 方法来更改注入的依赖项。

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

对此的任何帮助将不胜感激!

【问题讨论】:

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


【解决方案1】:

从大量的实验和研究来看,目前似乎无法移动 Startup 类,因为它存在不尊重使用 UseContentRoot 方法设置的 ContentRoot 路径的错误。此错误由 AspNetCore GitHub 上的 issue #11921 跟踪。

如果您需要能够从测试项目中注入依赖项,一个非常hacky 的解决方法是在您的主项目中创建一个静态类Dependencies,并带有一个静态Action&lt;IStartupConfiguration&gt; RegisterDependencies 字段,然后您可以在启动中调用它类:

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>();
};

这很hacky,希望ContentRoot问题得到修复,然后应该使用将内容根目录更改为主项目

【讨论】:

  • 可能是一个愚蠢的问题,但你为什么不这样使用:Program.CreateHostBuilder(new string[0]).Build().RunAsync(); 至少对我有用。我将两个项目通过.sln 文件绑定在一起。我是否遗漏了任何细节,为什么这不适用于您的情况?程序来自我的 blazor 服务器。
【解决方案2】:

对我来说,以下工作:

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

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

【讨论】:

    猜你喜欢
    • 2017-07-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-13
    • 1970-01-01
    • 2017-06-16
    • 1970-01-01
    相关资源
    最近更新 更多