c# - 如何在 ASP.Net Core 2.2 中对 CreatedAtAction 路由值进行单元测试以停止运行时失败
问题描述
在将我的 API 从 ASP.Net Core 2.1 升级到 2.2 后,我在运行时遇到了一些 InvalidOperationException 异常。
调用栈
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 }
});
}
解决方案
推荐阅读
- git - 将master合并到主分支
- pdf - 在 adobe reader 上使用 itextsharp 时显示数字签名字体时出错
- ionic-framework - React-Hook-Forms 和 Ionic - 如何使用表单外的按钮提交表单
- reactjs - ScaleY 一个 svg,后跟以下文本 div:React 版本
- python - 如何通过 Python 使用 Google Apps 脚本?
- reactjs - 在 Heroku 中运行 npm run build 以服务于烧瓶后端反应前端应用程序
- python - 问题在 Django 文件上呈现函数
- selenium - Jmeter webdriver 采样器:Webdriver 采样器和 http 采样器请求不会同时被命中
- postgresql - 找出所有至少连续出现 3 次的数字 | 无论如何使用窗口功能来实现这一点?
- javascript - pugjs 中的 setInterval