【问题标题】:With FluentValidation how can I test using validationContext within a controller使用 FluentValidation 如何在控制器中使用 validationContext 进行测试
【发布时间】: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);
}

. . .

显然,我可以只传入一个带有错误日期的视图模型,这会标记这一点,但感觉就像我正在测试控制器中的验证器。我真正想做的(我认为)是传递一个具有任意日期的视图模型,让验证器在该规则上失败,然后断言错误已添加到模型状态。任何帮助表示赞赏。

-珍妮

【问题讨论】:

    标签: c# asp.net-core fluentvalidation


    【解决方案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(...) 方法的视图模型的形式。
    猜你喜欢
    • 1970-01-01
    • 2022-01-11
    • 2018-10-01
    • 1970-01-01
    • 2012-09-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多