Testing of the ValidationProperties is quite simple. You just call yourAttribute.IsValid method with instance of some test class. But we found that if you annotate you custom attribute with
[AttributeUsage(AttributeTargets.Property)]
The IsValid method is not executed. Ok, there are another possibilities how to test validation attributes. We can use System.ComponentModel.DataAnnotations.Validator class and its methods TryValidateObject (for classes) and TryValidateProperty (for properties). For this purpose I have created helper class for testing these attributes for both object(class) and property.
public class ValidationAttributeTestHelper { public static IList<ValidationResult> GetValidationErrorsForObject(object model) { var validationContext = new ValidationContext(model, null, null); var validationResults = new List<ValidationResult>(); Validator.TryValidateObject(model, validationContext, validationResults); return validationResults; } public static void CheckValidationErrorsForObject(object model, IEnumerable<string>; expectedValidationMessages) { var errors = GetValidationErrorsForObject(model); errors.Count.ShouldBeEquivalentTo(expectedValidationMessages.Count()); var i = 0; foreach (var msg in expectedValidationMessages) { msg.ShouldBeEquivalentTo(errors[i++].ErrorMessage); } } public static IList<ValidationResult> GetValidationErrorsForProperty(object model, object property, string propertyName) { var validationContext = new ValidationContext(model, null, null) { MemberName = propertyName }; var validationResults = new List<ValidationResult>(); Validator.TryValidateProperty(property, validationContext, validationResults); return validationResults; } public static void CheckValidationErrorsForProperty(object model, object property, string propertyName, IEnumerable<string> expectedValidationMessages) { var errors = GetValidationErrorsForProperty(model, property, propertyName); errors.Count.ShouldBeEquivalentTo(expectedValidationMessages.Count()); var i = 0; foreach (var msg in expectedValidationMessages) { msg.ShouldBeEquivalentTo(errors[i++].ErrorMessage); } } }
The usage of this helper class is following:
- Create a test class which will be annotated with attributes to be tested
- Use the test helper class
public class TestClass { public string Password { get; set; } [NotEqualTo("Password")] //tested attribute public string PasswordCheck { get; set; } } [TestMethod] public void Test_NotEqualToAttribute_With_Set_Same_Passwords_Should_Return_Invalid_Result() { //Arrange var testee = new TestClass { Password = "samePassword", PasswordCheck = "samePassword" }; //Act //Assert ValidationAttributeTestHelper.CheckValidationErrorsForProperty(testee, testee.PasswordCheck, "PasswordCheck", new[] { "PasswordCheck cannot be the same as Password" }); }
Thats all.