This project has moved. For the latest updates, please go here.
1
Vote

Overload for ShouldHaveChildValidator() test method, accepting an instance of the model to test conditionals

description

Given the following models and validation rules:
//models
public class Person
{
    public string FirstName {get; set; }
    public string LastName {get; set;}
    public bool HasAddress {get; set;}
    public Address Address {get; set;}
}

public class Address
{
   public string Street1 {get; set;}
   public string Street2 {get; set;}
   public string City {get; set;}
   public string State {get; set;}
   public string Zip {get; set;}
}

//Validators
public class PersonValidator : AbstractValidator<Person>
{
    RuleFor(x => x.FirstName).NotEmpty();
    RuleFor(x => x.LastName).NotEmpty();
    RuleFor(x => x.HasAddress).NotEmpty();
    When(x => x.HasAddress, () =>
    {
        RuleFor(x => x.Address).SetValidator(new AddressValidator());
    });
}

public class AddressValidator : AbstractValidator<Address>
{
    public AddressValidator()
    {
        RuleFor(x => x.Street1).NotEmpty().Length(1, 100);
        RuleFor(x => x.Street2).Length(1, 100);
        RuleFor(x => x.City).NotEmpty().Length(1, 50);
        RuleFor(x => x.State).NotEmpty();
        RuleFor(x => x.Zip).NotEmpty().Length(5, 10).Matches(@"^\d{5}(-\d{4}){0,1}$");
    }
}
The AddressValidator is only set on the "Address" child property of Person, if HasAddress is true. For unit testing purposes, it would be nice to test this condition like so:
[TestMethod]
public void Address_Should_Have_ChildValidator_When_HasAddress_Is_True()
{
    AddressValidator validator = new AddressValidator();
    var model = new Person{
        FirstName = "John"
        LastName = "Smith",
        HasAddress = true,
        Address = new Address{
             Street1 = "123 Main St."
             City = "Anytown",
             State = "CA",
             Zip = "12345"
         }
    };
    validator.ShouldHaveChildValidator(x => x.Address, typeof(Address), model);
}
This would be similar to how you can test for conditional "when" statements when using the ShouldHaveValidationErrorFor() and ShouldNotHaveValidationErrorFor() methods, as they both have an overload that accepts an instance of the model class.

Would this be possible to create this method overload? If this is something you're willing to support, it probably also makes sense to have an inverse method - "ShouldNotHaveChildValidator()" since most people would also want to test the other case.

comments