2

我们有一个 MVC.NET Core Web API 应用程序,它使用操作过滤器来验证控制器方法的参数。

对于验证,我们使用 FluentValidation 框架。在动作过滤器中,我们找到控制器动作的参数在IValidator<TModel>哪里,例如:TModel

public async Task<IActionResult> Post([FromBody] TModel model)
{
}

在过滤器中OnActionExecuting(ActionExecutingContext context),我们找到正确的验证器 ( IValidator<TModel>),验证参数 ( context.ActionArguments),如果验证失败,我们通过将验证结果分配给 - 进行短路,context.Result这意味着执行永远不会到达控制器。

基本原理类似于将 FluentValidation 连接到 MVC 的 ModelState 验证管道中,但我们需要一些额外的东西,所以我们手动进行。

我们想对控制器和验证器进行单元测试。问题在于对控制器进行单元测试。在测试设置中,我们实例化控制器并调用其方法之一。现在在生产环境中,参数将始终得到验证,并且只有在参数有效时才会真正进入控制器方法。但是当对控制器进行单元测试时,我们很容易传递无效的参数并得到意外的行为。

原则上,有没有办法解决这个问题?或者我是否真的需要确保在测试方法中我将有效参数传递给控制器​​?

编辑:

我们还计划进行集成测试(很可能使用 .NET Core 的 TestServer)以确保管道正常工作。在这篇文章中,我只想讨论从单元测试方法传递到控制器的无效参数的问题。

4

3 回答 3

1

您需要在 ASP.NET Core 中编写集成测试,请参阅链接:https ://docs.microsoft.com/en-us/aspnet/core/testing/integration-testing?view=aspnetcore-2.0

主要目标:您测试相同的 Web api,但它托管在您的测试中。

于 2018-04-21T07:50:58.473 回答
0

首先对验证器进行单元测试,这样您就可以清楚地定义哪些参数有效,哪些无效。

然后,正如您在问题中所建议的那样,您可以只采用有效输入并专注于它们以对控制器进行单元测试。

最后,您可以使用有效和无效参数创建一些集成测试。

于 2018-04-20T22:23:07.627 回答
0

我同意Nkosi在评论中说的,因为required属性不是控制器直接使用的,而是框架modelbinder用来验证的(流利的验证也是基于那个),所以单独调用控制器方法不能单元测试这个属性的存在。它必须与框架进行集成测试。但是asp.net核心集成测试框架太重了,它可以测试整个流程,而不仅仅是模型绑定。我们需要一个模型绑定集成测试框架,运行它可以断言模型状态是否有效,而不关心实际的控制器动作结果。也许我们可以自己写一个。

于 2020-12-23T05:18:33.133 回答