После обновления моего API с ASP.Net Core 2.1 до 2.2 я столкнулся с некоторыми исключениями InvalidOperationException во время выполнения.
Callstack
System.InvalidOperationException:
at Microsoft.AspNetCore.Mvc.CreatedAtActionResult.OnFormatting (Microsoft.AspNetCore.Mvc.Core, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60)
at Microsoft.AspNetCore.Mvc.Infrastructure.ObjectResultExecutor.ExecuteAsync (Microsoft.AspNetCore.Mvc.Core, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60)
at Microsoft.AspNetCore.Mvc.ObjectResult.ExecuteResultAsync (Microsoft.AspNetCore.Mvc.Core, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60)
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker+<InvokeResultAsync>d__20.MoveNext (Microsoft.AspNetCore.Mvc.Core, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60)
Причина
Это произошло из-за отсутствия параметра в моем CreatedAtAction.
public async Task<IActionResult> GetFields([FromRoute]Guid productId)
{
return Ok(await _prodRepo.GetProductFields(productId));
}
public async Task<IActionResult> CreateFields([FromRoute]Guid productId, [FromBody]ProductField[] fields)
{
...
return CreatedAtAction(nameof(GetFields), fields);
}
Разрешение
Последняя строка должна включать productId
значение маршрута следующим образом:
return CreatedAtAction(nameof(GetFields), { productId }, fields);
Та же ошибка возникает, когда имена значений маршрута не совпадают.Это не вызвало исключений во время выполнения в 2.1, но я полагаю, что оно молча провалилось для всех, кто полагается на возвращаемый URL.
Большая проблема
Такое же исключение возникает во время выполненияесли значения маршрута имеют неправильное имя.Код компилируется без ошибок и предупреждений и дает сбой во время выполнения.
Меня беспокоит то, что эти ошибки легко вводить и легко пропустить во время разработки и только поверхность во время выполнения .У нас есть команда разработчиков, активно работающих над этим проектом Web API.Это произойдет снова при изменении сигнатуры метода действия, на которую ссылается результат CreatedAtAction
других действий.
Как выполнить модульное тестирование для этого случая ошибки? Я не хочу получатьчтобы выполнить интеграционные тесты на всех конечных точках API для обнаружения ошибок времени выполнения перед развертыванием.
Попытка
Я попробовал следующее, но потом обнаружил, что мне нужен UrlHelper, и получилзастрял в этой точке.
[Fact]
public void Test_CreateFields_CreatedAtAction_Values()
{
var fields = new ProductFieldRel { ProductId = _productId };
var task = _controller.CreateFields(_productId, new[] { fields });
var result = task.Result as CreatedAtActionResult;
Assert.NotNull(result);
result.OnFormatting(new ControllerContext
{
HttpContext = new DefaultHttpContext { User = _user }
});
}