Reputation: 2032
I'm using the FluentValidation library in an ASP.NET MVC project and, from a UI perspective, it's working as expected. Rule violations display the correct errors.
I have a parent class that has a validator and a collection property where that type has a validator. It's conceptually the same as described in the documentation.
I have a validator for a parent class...
public class MyFormValidator : AbstractValidator<MyFormViewModel>
...and I have a collection in MyFormViewModel
...
public IList<ChildRow> ChildRowsAdded { get; set; }
...and I create a validator for the collection of that child class...
public class ChildRowValidator : AbstractValidator<ChildRow>
...and I use that child validator in the parent validator...
RuleFor(m => m.ChildRowsAdded).SetCollectionValidator(new ChildRowValidator());
While writing some unit tests, I noticed that ShouldHaveValidationErrorFor
is not confirming the errors exist.
_validator.ShouldHaveValidationErrorFor(x => x.ChildRowsAdded, model);
That line in my test does not seem to see the errors. The test fails and the message says
FluentValidation.TestHelper.ValidationTestException : Expected a validation error for property AllergyRowsAdded.
If I manually .Validate()
and look at the results, I see the error.
Has anyone run into this before? Is there an additional step I need to take to use ShouldHaveValidationErrorFor
in this situation?
Upvotes: 8
Views: 10085
Reputation: 456
Now, we can do it like that:
in child validator:
RuleForEach(request => request.ChildRowsAdded)
.SetValidator(new ChildRowValidator())
.When(request => request.ChildRowsAdded != null); // whatever your rule
And
var result = _validator.TestValidate(model);
result.ShouldHaveValidationErrorFor(x => x.ChildRowsAdded);
Upvotes: 1
Reputation: 5281
According to the docs, there is another way to test nested properties: a string name that represents the path to the nested property:
// You can also use a string name for properties that can't be easily represented with a lambda, eg: result.ShouldHaveValidationErrorFor("Addresses[0].Line1");
Upvotes: 10
Reputation: 6782
Jookin is absolutely right in his comment:
ShouldHaveValidationErrorFor
method doesn't designed to validate properties of properties, you can read about it here.
There are 2 solutions:
ShouldHaveValidationErrorFor
and test ChildRowValidator
directly, like this: _childValidator.ShouldHaveValidationErrorFor(x => x.Name, childModel);
// direct descendant property can be validated
Assert
class to check, if in ValidationResult
object exists any error with name, that match your array item(s) property by regexp or simple string comparison. Choose one, that much more meet your purposes.
Upvotes: 7