【问题标题】:Cannot get index.html from a NUnit test无法从 NUnit 测试中获取 index.html
【发布时间】:2020-08-20 06:19:06
【问题描述】:

我尝试使用 NUnit 和 Asp.net-core-hosted Blazor WebAssembly Application 编写端到端测试。

我使用 3.1.7 模板创建了一个新项目。 然后我只是添加一个 NUnit 项目并编写简单的测试。

private const string serviceUrl = "https://localhost:50200";
private HttpClient _httpClient;

[OneTimeSetUp]
public void Init()
{
    var arguments = new string[0];
    var builder = Program.CreateHostBuilder(arguments);

    _httpClient = new HttpClient();

    builder
        .ConfigureWebHostDefaults(w => w.UseUrls(serviceUrl))
        .Build()
        .Start();
}

[Test]
public async Task HomePageResponcesOk()
{            
    var requestUrl = serviceUrl;
    var response = await _httpClient.GetAsync(requestUrl);
    Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
}

[Test]
public async Task ApiResponcesOk()
{
    var requestUrl = $"{serviceUrl}/WeatherForecast";
    var response = await _httpClient.GetAsync(requestUrl);
    Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
}

我没有改变其他任何东西。

我得到下一个结果

Test                        Duration  Error Message
HomePageResponcesOk Failed  45 ms     Expected: OK   But was:  NotFound 
ApiResponcesOk      Passed  364 ms      

我做错了什么?

我可以指出,它在更早期的 Blazor WebAssembly 版本中运行良好。


我还添加了另外两个测试

[Test]
public async Task AppCssResponcesOk()
{
    var requestUrl = $"{serviceUrl}/css/app.css";
    var response = await _httpClient.GetAsync(requestUrl);
    Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
}

[Test]
public async Task WebAssemblyResponcesOk()
{
    var requestUrl = $"{serviceUrl}/_framework/blazor.webassembly.js";
    var response = await _httpClient.GetAsync(requestUrl);
    Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
}

它们返回相同的结果Failed 45 ms Expected: OK But was: NotFound

我认为app.UseStaticFiles(); 不能按我的预期工作。可能是真的吗?如何解决?


所以,当测试项目启动时,后端不知道 wwwroot 在哪里。可以用UseWebRoot()修复。

builder
    .ConfigureWebHostDefaults(w =>
    {
        w.UseUrls(serviceUrl);
        w.UseWebRoot(@"..\..\..\..\BlazorApp2\Client\wwwroot");
    })
   .Build()
   .Start();

所有测试都成功通过,WebAssemblyResponcesOk() 除外。这是因为文件放在另一个目录\BlazorApp2\Client\bin\Debug\netstandard2.1\wwwroot\_framework 中。 如果我添加第二个.UseWebRoot(),那么只会取消第一个。


好的,我用调试器深入研究 ASP.Net Core 源代码。

还有下一个事实。

如果运行后端项目,则 StaticFileMiddleware 类中的 _fileProvider 字段将获得具有下一个结构的复数:

CompositeFileProvider-- ._fileProviders
                               |                  
                               +-- NullFileProvider
                               |
                               +-- StaticWebAssetsFileProvider-- .InnerProvider
                                                                       |
                                                             PhysicalFileProvider
                               |
                               +-- StaticWebAssetsFileProvider-- .InnerProvider
                                                                       |    
                                                             PhysicalFileProvider

一个PhysicalFileProvider在源代码中定位到wwwroot,另一个定位到/bin中的wwwroot

如果运行测试,StaticFileMiddleware _fileProvider 将得到简单的 PhysicalFileProvider 目标作为 UseWebRoot() 参数。如果我返回没有UseWebRoot() 的版本,NullFileProvider 将在那里设置。

现在我可以意识到一开始发生了什么。但我仍然不知道对 StaticFileMiddleware 文件提供程序有什么影响。类构造函数通过IOptions<StaticFileOptions> 的注入获取值。

我应该在哪里设置断点来捕获这种类型的 DI 注册?

【问题讨论】:

  • 它在浏览器中工作吗?
  • @DIlshodK。如果我直接启动后端项目“BlazorApp.Server”,它会完美运行。如果我要在调试模式下运行测试,然后转到 localhost:50200,我将收到浏览器 404 消息。如果我去 localhost:50200/WeatherForecast 我会看到 json 结果。
  • 它对我有用。你能在 Github 上分享你的项目吗?
  • 从我的脑海中浮出水面 - 你试过使用TestServer吗?它将IWebHostBuilder 作为构造函数参数,并有一个CreateClient() 方法返回HttpClient
  • 另外,here's a good read 正在测试 Web 应用程序。

标签: c# asp.net-core nunit blazor blazor-client-side


【解决方案1】:

根据您收到的响应,即 “NotFound”,我的第一个猜测是为获取该特定文件而创建的路径可能不正确。如果我要调试它,我可能会尝试一些 “MapFallbackToFile” 函数的重载。需要显式路径(绝对或相对)或其他属性的路径。经过一番尝试和尝试,您也许可以找到相应的文件。

您可以做的另一件事是加快调试过程,即您可以通过编程方式检查当前工作目录并将其用作参考点来构建所需的准确文件路径。这可以使用以下命令完成:

System.IO.Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);

一个非常常见的错误是我们的程序经常在构建目录中运行(例如 bin/debug/..),而我们需要的文件(例如 css 或 image)文件不存在在那里,因此,我们会遇到这样的问题.这是解决此问题的一种方法。

【讨论】:

    【解决方案2】:
    1. 我已将 *.StaticWebAssets.xml 文件从 ...\Server\bin\Debug\netcoreapp3.1 复制到 ...\NUnitTestProject1\bin\Debug\netcoreapp3.1

    2. 我已将UseStaticWebAssets() 添加到后端启动代码中。

      builder
       .ConfigureWebHostDefaults(w =>
       {
           w.UseUrls(serviceUrl);
           w.UseStaticWebAssets();
       })
      .Build()
      .Start();
      

    所有测试都通过了。调试器显示CompositeFileProvider 注入与后端手动启动时的结构相同...

    我已经在构建事件中设置了这些文件的复制

    <Target Name="PostBuild" AfterTargets="PostBuildEvent">
        <Exec Command="copy ..\Rest\bin\$(ConfigurationName)\net5.0-windows\*.StaticWebAssets.xml .\bin\$(ConfigurationName)\net5.0-windows\*.*" />
    </Target>
    

    很遗憾,我无法实现如何在测试项目中实现自动生成 StaticWebAssets.xml。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-03-08
      • 2021-12-26
      • 1970-01-01
      • 2011-09-16
      • 1970-01-01
      • 1970-01-01
      • 2015-06-03
      • 1970-01-01
      相关资源
      最近更新 更多