使用FluentValidator验证属性的儿童 [英] Using FluentValidator to validate children of properties
问题描述
我想用FluentValidation来验证一些类,其中一个只用来作为一个属性上的另一个...但我从来不直接创建子类,所以我想从父级别测试验证。这可能是不必要/疯狂
I want to use FluentValidation to validate some classes one of which is only used as a property on another... but I never directly create the child class so I want to test validation from the parent level. This may be unnecessary / crazy
因此,例如我有
public class Parent
{
public string Text {get;set;}
public Child Child {get;set;}
}
public class Child
{
public string Text {get;set;}
}
和
public class ParentValidator : AbstractValidator<Parent>
{
public ParentValidator()
{
RuleFor(p=>p.Text).NotEmpty();
//RuleFor(p=>p.Child).SetValidator(new ChildValidator);
//RuleFor(p=>p.Child.Text).NotEmpty();
}
}
public class ChildValidator : AbstractValidator<Child>
{
public ChildValidator()
{
RuleFor(c=>c.Text).NotEmpty();
}
}
这是我测试用
which I test using
[Test]
public void ParentMustHaveText()
{
new ParentValidator()
.ShouldHaveValidationErrorFor(p => p.Text, "");
}
[Test]
public void ChildMustHaveText()
{
new ParentValidator().ShouldHaveValidationErrorFor(p => p.Child.Text, "");
}
的
ChildMustHaveText
测试总是失败无论我怎么设置的东西了。我是不是疯了想测试这种方式?
The ChildMustHaveText
test always fails no matter how I set things up. Am I being crazy trying to test it that way?
因为下面的测试总是通过
since the following test always passes
[Test]
public void ChildMustHaveText()
{
new ChildValidator().ShouldHaveValidationErrorFor(c => c.Text, "");
}
的类是在ASP.NET的WebAPI项目模型。
The classes are models in an ASP.NET WebApi Project.
推荐答案
第一个错误是,你忘了指定儿童
中的默认属性对象的创建父
构造 - FluentValidation尝试设置空
的dynanically财产
The first error is that you forget to specify creation of Child
property object in default Parent
constructor — FluentValidation try to set dynanically property of null
.
public class Parent
{
public Parent()
{
Child = new Child();
}
public string Text { get; set; }
public Child Child { get; set; }
}
注意,默认构造函数总是使用 ShouldHaveValidationErrorFor
进行验证之前创建对象。
Notice that default constructor always uses in ShouldHaveValidationErrorFor
for object creation before validation.
我发现接下来的事情是,目前执行 ShouldHaveValidationErrorFor
不允许检查与嵌套层次嵌套属性的有效期超过1 ( obj.Child1.Child2.Text
是嵌套3级,例如)。
The next thing I found is that current implementation of ShouldHaveValidationErrorFor
doesn't allow to check validity of nested properties with nesting level more than 1 (obj.Child1.Child2.Text
is level 3 of nesting, for example).
缺陷的
PITFALL
越野车的地方源代码( FluentValidation.TestHelper.ValidatorTester
类):
Source code of buggy place (FluentValidation.TestHelper.ValidatorTester
class):
public void ValidateError(T instanceToValidate) {
accessor.Set(instanceToValidate, value);
//
var count = validator.Validate(instanceToValidate, ruleSet: ruleSet).Errors.Count(x => x.PropertyName == accessor.Member.Name);
if (count == 0) {
throw new ValidationTestException(string.Format("Expected a validation error for property {0}", accessor.Member.Name));
}
}
说明的
EXPLANATION
方法进行比较验证错误加盟属性名( x.PropertyName
)财产的对象 System.Reflection.RuntimePropertyInfo
名( accessor.Member.Name
),例如: 文字
和Child.Text
与文字
这两个测试,所以检验合格的,只是因为 parent.Text
为空,这不是等于在两个相互有效和属性名类。
Method compares joined property names with validation errors (x.PropertyName
) with property object System.Reflection.RuntimePropertyInfo
name (accessor.Member.Name
), e.g. "Text"
and "Child.Text"
with "Text"
for both tests, so test pass only because of parent.Text
is null, it's not valid and property names equal to each other in both classes.
如果简化 - 现在你的测试通过,但错误的原因
If simplify — now your test passes, but by wrong reason.
您可以看到这种奇怪的行为,如果重新命名字符串属性之一:
You can see this strange behavior if you rename one of string property:
public class Child
{
public string Text2 {get;set;}
}
如果您 Parent.Text
财产有效的测试(删除规则,或父()
违约,不为空值的构造函数)。
or if you make Parent.Text
property valid in tests (remove rule, or initialize in Parent()
default constructor by not empty value).
public Parent()
{
Child = new Child();
Text = "I like pitfalls";
}
结论的
CONCLUSION
这是在TestHelper类的错误,我希望这项研究可以帮助你在未来的测试策略,为您的应用决定。
It's a bug in TestHelper class, and I hope this research helps you to decide on future test strategy for your application.
和永不放弃! ; - )
And never give up! ;-)
这篇关于使用FluentValidator验证属性的儿童的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!