Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to write Unit Test for IValidatableObject Model

I have created a ViewModel as below.

   public class ProjectViewModel: IValidatableObject
    {
        public int ProjectID { get; set; }

        [DisplayName("Name")]
        [Required]
        public string Name { get; set; }

        [DisplayName("Start Date")]
        public DateTime StartDate { get; set; }

        [DisplayName("End Date")]
        [Compare("EndDate")]
        public DateTime EndDate { get; set; }

        [DisplayName("Project States")]
        public List<ProjectStateViewModel> States { get; set; }
        public string PageTitle { get; set; }


        public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
        {
            List<ValidationResult> res = new List<ValidationResult>();
            if (EndDate <= StartDate)
            {
                res.Add( new ValidationResult(ErrorMessage.END_DATE_AFTER_START_DATE));
            }

            return res;
        }
    }

Also written the below test case

[TestMethod]
[ExpectedException( typeof(ValidationException),"End Date must be greater than Start Date.")]
public void Create_New_Project_EndDate_Earlier_StartDate()
{
    ProjectViewModel model = new ProjectViewModel
    {
        ProjectID = 3,
        Name = "Test Project",
        StartDate = DateTime.Now.Date,
        EndDate = DateTime.Now.AddMonths(-1),
        States = new List<ProjectStateViewModel> { new ProjectStateViewModel { StateName = "Pending" } }
    };

    Task<ActionResult> task = _projectController.Edit(model);

    ViewResult result = task.Result as ViewResult;

}

it works fine when actual code executing in MVC app through browser. But ModelState.IsValid returns always true in my Unit test and it fails. Later I understood that Validation is not executed by controller. Controller received the model after Validation happens so it'll have appropriate ModelState. My question is what should be my approach to write unit test for Model Validation or should I write it at all?

like image 621
Nps Avatar asked Jul 06 '14 05:07

Nps


1 Answers

You can just call the method directly and assert against it's results.

[TestMethod]
public void Create_New_Project_EndDate_Earlier_StartDate()
{
    ProjectViewModel model = new ProjectViewModel
    {
        ProjectID = 3,
        Name = "Test Project",
        StartDate = DateTime.Now.Date,
        EndDate = DateTime.Now.AddMonths(-1),
        States = new List<ProjectStateViewModel> { new ProjectStateViewModel { StateName = "Pending" } }
    };

    var validationContext = new ValidationContext(model);

    var results = model.Validate(validationContext);

    Assert.AreEqual(results.Count(), 1);
    Assert.AreEqual(results.First().ErrorMessage, "End Date must be greater than Start Date.");
}
like image 124
John M. Wright Avatar answered Sep 21 '22 00:09

John M. Wright