2015-01-14 4 views
5

Я хочу использовать FluentValidation для проверки некоторых классов, один из которых используется только как свойство для другого ... но я никогда не создавал дочерний класс, поэтому я хочу проверить валидность с родительского уровень. Это может быть ненужным/сумасшедшийИспользование FluentValidator для проверки дочерних объектов свойств

Так, например, у меня есть

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(); 
    } 
} 

который я тест с использованием

[Test] 
    public void ParentMustHaveText() 
    { 
     new ParentValidator() 
      .ShouldHaveValidationErrorFor(p => p.Text, ""); 
    } 
    [Test] 
    public void ChildMustHaveText() 
    { 
     new ParentValidator().ShouldHaveValidationErrorFor(p => p.Child.Text, ""); 
    } 

Испытание ChildMustHaveText всегда терпит неудачу, независимо от того, как я все наладилось. Я что, сумасшедший, пытаюсь это проверить?

, так как следующий тест всегда проходит

[Test] 
    public void ChildMustHaveText() 
    { 
     new ChildValidator().ShouldHaveValidationErrorFor(c => c.Text, ""); 
    } 

Классы модели в проекте ASP.NET WebAPI.

+0

Я не хочу выглядеть тупым, но ваши определения правил для детской собственности прокомментированы. –

+0

Да, это может быть непонятно. Независимо от того, какую комбинацию я настраивал, я не мог пройти тест. Я просто сдался в конце –

ответ

5

Привеливство по ошибке так: что вы не забыли указать объект объекта Child по умолчанию Parent constructor - FluentValidation попытаться установить динамическое свойство null.

public class Parent 
{ 
    public Parent() 
    { 
     Child = new Child(); 
    } 

    public string Text { get; set; } 
    public Child Child { get; set; } 
} 

Обратите внимание, что конструктор по умолчанию всегда используется в ShouldHaveValidationErrorFor для создания объекта Перед проверкой.

Следующая вещь, которую я нашел, что текущая реализацияShouldHaveValidationErrorForне позволяет проверить правильность вложенных свойств с уровнем вложенности более 1 (obj.Child1.Child2.Text является уровень 3 вложенности, например).

ловушкой

Исходный код багги место (FluentValidation.TestHelper.ValidatorTester класс):

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)); 
     } 
    } 

ПОЯСНЕНИЕ

Метод сопоставляются присоединился имена свойств с ошибками валидации (x.PropertyName) с объектом собственности System.Reflection.RuntimePropertyInfo имя (accessor.Member.Name), т.е. "Text" и "Child.Text" с "Text"для обоих тестов, поэтому тестовый проход только из-за parent.Text имеет значение null, он недопустим и имена свойств равны между собой в обоих классах.

Если упростить - теперь ваш тест проходит, но по неправильной причине.

Вы можете увидеть это странное поведение, если вы переименовать одну из строкового объекта:

public class Child 
{ 
    public string Text2 {get;set;} 
} 

или если вы сделаете Parent.Text свойство действует в тестах (удалить правило, или инициализировать в Parent() конструктор по умолчанию, не пустое значение).

public Parent() 
{ 
    Child = new Child(); 
    Text = "I like pitfalls"; 
} 

ЗАКЛЮЧЕНИЕ

Это ошибка в классе TestHelper, и я надеюсь, что это исследование поможет вам принять решение о будущей стратегии испытаний для вашего приложения.

И никогда не сдавайтесь! ;-)

Смежные вопросы