使用 FluentValidation 如何在控制器中使用 validationContext 进行测试
Posted
技术标签:
【中文标题】使用 FluentValidation 如何在控制器中使用 validationContext 进行测试【英文标题】:With FluentValidation how can I test using validationContext within a controller 【发布时间】:2021-11-19 15:45:40 【问题描述】:我设置了一个验证器,它需要使用正在验证的视图模型之外的值。所以要做到这一点,我使用 ValidationContext 并分配 RootContextData,然后在控制器中调用 validate 方法,如果它返回错误,我将它添加到模型状态。这一切都很好,但我不知道如何测试它,或者这可能表明我没有以最好的方式完成它。
例如验证者:
RuleFor(x => x.StartDate.Date.Day)
.Custom((day, context) =>
if (!context.RootContextData.TryGetValue("TargetDate", out var targetDate)) return;
var dateVm = context.InstanceToValidate;
if (DatesHelper.SourceDateStringIsGreaterThanTargetDateString(
dateVm.StartDate.DateInputAsString(),
targetDate as string) == true)
context.AddFailure("The Start date must be on or before the target date for the action");
);
然后在控制器中..
. . .
var repositoryResult = customerRepo.Result;
if (!ModelState.IsValid)
return View(vm);
var validationContext = new ValidationContext<StartDateViewModel>(vm)
RootContextData =
["TargetDate"] = repositoryResult.Dates.Target
;
var validator = new StartDateValidator();
var validationResult = await validator.ValidateAsync(validationContext);
if (!validationResult.IsValid)
ModelState.AddModelError("StartDate.Date.Day", validationResult.Errors.First().ErrorMessage);
return View(vm);
. . .
显然,我可以只传入一个带有错误日期的视图模型,这会标记这一点,但感觉就像我正在测试控制器中的验证器。我真正想做的(我认为)是传递一个具有任意日期的视图模型,让验证器在该规则上失败,然后断言错误已添加到模型状态。任何帮助表示赞赏。
-珍妮
【问题讨论】:
【参考方案1】:我认为您可以做的是测试控制器逻辑。 一个例子可能是这样的:
[Test]
public void IndexPost_AddModelStateError_WhenInvalidData()
var controller = new HomeController();
var vm = ... //Test Data
var result = controller.Index(vm) as ViewResult;
Assert.IsTrue(result.ViewData.ModelState["StartDate.Date.Day"].Errors.Any());
Here你可以找到微软关于测试控制器逻辑的文档
【讨论】:
我应该说,是的,这是我正在努力测试的控制器。您的方法的问题是我必须提供会触发验证的测试数据,因此如果有意义的话,就不会真正孤立地测试控制器。这就是重点,但我想我可以做到这一点,不要想太多!谢谢 @Blingers:你不能单独测试控制器,因为它依赖于视图模型。所以是的,您必须提供“测试数据”,因为这是控制器的依赖项,以传递给Index(...)
方法的视图模型的形式。以上是关于使用 FluentValidation 如何在控制器中使用 validationContext 进行测试的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Web API 中使用 FluentValidation 执行异步 ModelState 验证?
使用 WebApi [Route] 属性时 FluentValidation 不起作用
FluentValidation 返回错误时如何返回自定义响应?
在 .NET 中使用 FluentValidation 进行参数验证