Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

FluentValidation ShouldHaveValidationErrorFor with SetCollectionValidator

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?

like image 634
Mattio Avatar asked Jun 11 '26 05:06

Mattio


2 Answers

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");
like image 181
Aaron Thomas Avatar answered Jun 13 '26 05:06

Aaron Thomas


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:

  1. Use ShouldHaveValidationErrorFor and test ChildRowValidator directly, like this: _childValidator.ShouldHaveValidationErrorFor(x => x.Name, childModel); // direct descendant property can be validated
  2. Avoid this helper method and use 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.


Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!