问题
apologized to post bit similar question here. i am bit familiar with asp.net mvc but very new in unit testing. do not think that i know lot just see my reputation in stackoverflow.
i like to know how to write unit test code for IsValid
and IEnumerable<ModelClientValidationRule> GetClientValidationRules
here i am pasting my code including my model. so anyone help me to write unit test code for the above two function. i am new in unit testing and working with VS2013 and using VS unit testing framework.
my main problem is how to write unit test code for this function specifically IEnumerable<ModelClientValidationRule> GetClientValidationRules
so here is my full code. anyone who often work with unit test then please see and come with code and suggestion if possible. thanks
Model
public class DateValTest
{
[Display(Name = "Start Date")]
[DataType(DataType.Date), DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}", ApplyFormatInEditMode = true)]
public DateTime? StartDate { get; set; }
[Display(Name = "End Date")]
[DataType(DataType.Date), DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}", ApplyFormatInEditMode = true)]
[DateGreaterThanAttribute(otherPropertyName = "StartDate", ErrorMessage = "End date must be greater than start date")]
public DateTime? EndDate { get; set; }
}
custom validation code
public class DateGreaterThanAttribute : ValidationAttribute, IClientValidatable
{
public string otherPropertyName;
public DateGreaterThanAttribute() { }
public DateGreaterThanAttribute(string otherPropertyName, string errorMessage)
: base(errorMessage)
{
this.otherPropertyName = otherPropertyName;
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
ValidationResult validationResult = ValidationResult.Success;
try
{
// Using reflection we can get a reference to the other date property, in this example the project start date
var containerType = validationContext.ObjectInstance.GetType();
var field = containerType.GetProperty(this.otherPropertyName);
var extensionValue = field.GetValue(validationContext.ObjectInstance, null);
if(extensionValue==null)
{
//validationResult = new ValidationResult("Start Date is empty");
return validationResult;
}
var datatype = extensionValue.GetType();
//var otherPropertyInfo = validationContext.ObjectInstance.GetType().GetProperty(this.otherPropertyName);
if (field == null)
return new ValidationResult(String.Format("Unknown property: {0}.", otherPropertyName));
// Let's check that otherProperty is of type DateTime as we expect it to be
if ((field.PropertyType == typeof(DateTime) || (field.PropertyType.IsGenericType && field.PropertyType == typeof(Nullable<DateTime>))))
{
DateTime toValidate = (DateTime)value;
DateTime referenceProperty = (DateTime)field.GetValue(validationContext.ObjectInstance, null);
// if the end date is lower than the start date, than the validationResult will be set to false and return
// a properly formatted error message
if (toValidate.CompareTo(referenceProperty) < 1)
{
validationResult = new ValidationResult(ErrorMessageString);
}
}
else
{
validationResult = new ValidationResult("An error occurred while validating the property. OtherProperty is not of type DateTime");
}
}
catch (Exception ex)
{
// Do stuff, i.e. log the exception
// Let it go through the upper levels, something bad happened
throw ex;
}
return validationResult;
}
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
var rule = new ModelClientValidationRule
{
ErrorMessage = FormatErrorMessage(metadata.GetDisplayName()),
ValidationType = "isgreater",
};
rule.ValidationParameters.Add("otherproperty", otherPropertyName);
yield return rule;
}
}
回答1:
What you want to do is test that if the value of EndDate
is less than the value of StartDate
, then the model is invalid, i.e. that the IsValid()
method will throw a ValidationException
// Test that if the end date is less than the start date its invalid
[TestMethod]
[ExpectedException(typeof(ValidationException))]
public void TestEndDateIsInvalidIfLessThanStartDate()
{
// Initialize a model with invalid values
DateValTest model = new DateValTest(){ StartDate = DateTime.Today, EndDate = DateTime.Today.AddDays(-1) };
ValidationContext context = new ValidationContext(model);
DateGreaterThanAttribute attribute = new DateGreaterThanAttribute("StartDate");
attribute.Validate(model.EndDate, context);
}
When you run the test, if will succeed. Conversely if you were to initialize the model using
DateValTest model = new DateValTest(){ StartDate = DateTime.Today, EndDate = DateTime.Today.AddDays(1) };
the test would fail because the model is valid.
来源:https://stackoverflow.com/questions/36100027/asp-net-mvc-how-to-write-unit-test-code-when-working-with-validationattribute-a