使用FluentValidator验证属性的儿童 [英] Using FluentValidator to validate children of properties

查看:785
本文介绍了使用FluentValidator验证属性的儿童的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想用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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆