Thursday, June 14, 2012

Learning MVC: Unit Testing Validation in MVC

This is a rather short post. A little "trick" is required to test validation. If the Create function is called directly from the unit test, and the entity is validated using DataAnnotation validation, the model binder will not be invoked and the validation will not take place. The test result, obviously, will not be the expected one. To deal with that, it is necessary to mimic the behavior of the model binder. The following test creates a ValidationContext and uses the DataAnnotations.Validator class to validate the model.

[TestMethod()]
public void ValidateNameIsTooShort()
{
 Ingredient ingredient = new Ingredient() { IngredientName = "a" };

 var validationContext = new ValidationContext(ingredient, null, null);
 var validationResults = new List<ValidationResult>();
 Validator.TryValidateObject(ingredient, validationContext, validationResults);

 string error = GetValidationError(validationResults);

 Assert.AreEqual(error, Constants.Constants.IngredientNameTooShort);
}

If any errors are caught by the validation, they will be added to the ModelState of the controller. To get it back and compare with my expected error message, I just need to retrieve the first error message from the list of ValidationResult.

public string GetValidationError(List<ValidationResult> results)
{
 foreach (var result in results)
 {
  if(!String.IsNullOrEmpty(result.ErrorMessage))
  {
   return result.ErrorMessage;
  }
 }
 return string.Empty;
}

References:

Testing DataAnnotation-based validation in ASP.NET MVC
Unit tests on MVC validation
by . Also posted on my website

No comments: