Is it possible to test a FluentValidation PropertyValidator
in isolation?
I know I can test the Validator that's using the PropertyValidator
for specific errors but I’d rather test true/false just on the property validator if possible.
Can this be done? If so, how?
3 Answers
Answers 1
I also wanted to test my true / false logic. It is a shame the IsValid method is protected. My work around was to create another IsValid method and have the protected IsValid call through to it.
public class MyValidator: PropertyValidator { public MyValidator( string errorMessage = "default Message") : base(errorMessage) { } protected override bool IsValid(PropertyValidatorContext context) { var stringToValidate = context.PropertyValue as String; return IsValid(stringToValidate); } public bool IsValid(string stringToValidate) { if (stringToValidate == null) { return false; } //testing logic here return true; } }
Answers 2
I know this has been a while, but I achieved this as follows:
Custom Validator:
public class MyValidator : PropertyValidator { public MyValidator () : base("Value must be null or between 0 and 3.") { } protected override bool IsValid(PropertyValidatorContext context) { if (context.PropertyValue == null) { return true; } var value = (decimal)context.PropertyValue; return value >= 0m && value <= 3m; } }
Test Validator:
public class TestValidator : InlineValidator<TestObject> { public TestValidator (params Action<TestValidator >[] actions) { foreach (var action in actions) { action(this); } } }
Test Object:
public class TestObject { public TestObject(decimal? val) { this.GenericDecimal = val; } public decimal? GenericDecimal { get; set; } }
Test:
[Test] public void TestIt() { var validator = new TestValidator(v => v.RuleFor(obj => obj.GenericDecimal).SetValidator( new MyValidator() )); Assert.IsTrue(validator.Validate(new TestObject(null)).IsValid); Assert.IsTrue(validator.Validate(new TestObject(0m)).IsValid); Assert.IsTrue(validator.Validate(new TestObject(3m)).IsValid); Assert.IsFalse(validator.Validate(new TestObject(-1m)).IsValid); Assert.IsFalse(validator.Validate(new TestObject(3.01m)).IsValid); }
Answers 3
As for version 6.2 of FluentValidation it is possible to build the PropertyValidator.Validate() parameter due to making ValidatorSelectors globally configurable: https://github.com/JeremySkinner/FluentValidation/commit/95376c0519da1a06388be91a97fb5062fd4a162e
In the below example you see how I validate the 'puic' property of Track
Unit test:
public void ExistsInCollectionValidatorTest() { var track = new Track() { puic = "p1" }; var sut = new ExistsInCollectionValidator<Track>(); // Build PropertyValidator.Validate() parameter var selector = ValidatorOptions.ValidatorSelectors.DefaultValidatorSelectorFactory(); var context = new ValidationContext(track, new PropertyChain(), selector); var propertyValidatorContext = new PropertyValidatorContext(context, PropertyRule.Create<Track,string>(t => t.puic), "puic"); var results = sut.Validate(propertyValidatorContext); // Assertion.. }
0 comments:
Post a Comment