FluentValidation ShouldHaveValidationErrorFor 与 SetCollectionValidator

Mat*_*tio 7 asp.net-mvc fluentvalidation

我在 ASP.NET MVC 项目中使用 FluentValidation 库,从 UI 角度来看,它按预期工作。违反规则会显示正确的错误。

我有一个父类,它有一个验证器和一个集合属性,其中该类型有一个验证器。它在概念上与文档中描述的相同。

我有一个父类的验证器......

public class MyFormValidator : AbstractValidator<MyFormViewModel>
Run Code Online (Sandbox Code Playgroud)

...我有一个收藏MyFormViewModel...

public IList<ChildRow> ChildRowsAdded { get; set; }
Run Code Online (Sandbox Code Playgroud)

...我为该子类的集合创建一个验证器...

public class ChildRowValidator : AbstractValidator<ChildRow>
Run Code Online (Sandbox Code Playgroud)

...并且我在父验证器中使用该子验证器...

RuleFor(m => m.ChildRowsAdded).SetCollectionValidator(new ChildRowValidator());
Run Code Online (Sandbox Code Playgroud)

在编写一些单元测试时,我注意到这ShouldHaveValidationErrorFor并不能确认错误的存在。

_validator.ShouldHaveValidationErrorFor(x => x.ChildRowsAdded, model);
Run Code Online (Sandbox Code Playgroud)

我的测试中的那一行似乎没有看到错误。测试失败并显示消息

FluentValidation.TestHelper.ValidationTestException:预计属性 AllergyRowsAdded 出现验证错误。

如果我手动.Validate()查看结果,我会看到错误。

以前有人遇到过这个吗?ShouldHaveValidationErrorFor在这种情况下我需要采取额外的步骤吗?

Aar*_*mas 8

根据docs,还有另一种方法来测试嵌套属性:表示嵌套属性路径的字符串名称:

// You can also use a string name for properties that can't be easily represented with a lambda, eg:
result.ShouldHaveValidationErrorFor("Addresses[0].Line1");
Run Code Online (Sandbox Code Playgroud)


Evg*_*vin 7

Jookin 的评论绝对正确:

ShouldHaveValidationErrorFor方法并非旨在验证属性的属性,您可以在此处阅读相关内容。

有2种解决方案:

  1. 直接使用ShouldHaveValidationErrorFor并测试ChildRowValidator,如下所示:_childValidator.ShouldHaveValidationErrorFor(x => x.Name, childModel); // direct descendant property can be validated
  2. 避免使用此辅助方法并使用Assert类来检查ValidationResult对象中是否存在任何名称错误,通过正则表达式或简单的字符串比较来匹配您的数组项属性。

选择一个,更能满足您的目的。