Не могу получить index.html из теста NUnit

Я пытаюсь написать end-end тест используя NUnit для моего Blazor WebAssembly Asp.Net-core-hosted приложения.

Cоздал проект на основе шаблона 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.


Пытаюсь разобраться с помощью отладчика. Добавил мидлварь между .UseRouting() and .UseEndpoints.

app.UseRouting();
app.Use(TestMiddleware);
app.UseEndpoints(endpoints =>
{
    endpoints.MapRazorPages();
    endpoints.MapControllers();
    endpoints.MapFallbackToFile("index.html");
});

...

public Task TestMiddleware(HttpContext context, Func<Task> next)
{
    var endpoint = context.GetEndpoint();
    Console.WriteLine(endpoint.DisplayName);
    return next();
}

Добавил ещё тест

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

Тоже самое Failed 45 ms Expected: OK But was: NotFound. Может быть app.UseStaticFiles(); работает не так, как я ожидаю?


Попробовал переделать тесты c использованием WebApplicationFactory<Startup>().CreateClient() вместо Program.CreateHostBuilder(arguments);

private const string serviceUrl = "";
private WebApplicationFactory<Startup> _factory;    
private HttpClient _httpClient;

[OneTimeSetUp]
public void Init()
{
    _factory = new WebApplicationFactory<Startup>();
    _httpClient = _factory.CreateClient();
}

Все тесты проходят! Но мне такой вариант не подойдёт, т.к. я планирую использовать Selenium.


Ответы (2 шт):

Автор решения: 4per

Получается, что при запуске из проекта с тестами, бэкэнд почему-то не знает, где собственно находиться wwwroot. Лечиться с помощью UseWebRoot()

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

Все тесты теперь проходят.

Если кто знает как убрать хардкод пути, подскажите, пожалуйста.

→ Ссылка
Автор решения: 4per
  1. Скопировал из ...\Server\bin\Debug\netcoreapp3.1 в ...\NUnitTestProject1\bin\Debug\netcoreapp3.1 файлы *.StaticWebAssets.xml

  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>

К сожалению, не могу понять, как настроить генерацию этих файлов в проекте тестов автоматически.

→ Ссылка