如何为IValidatableObject模型编写单元测试

时间:2014-07-06 05:33:06

标签: asp.net-mvc-4 unit-testing

我已经创建了一个ViewModel,如下所示。

   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;
        }
    }

还写下面的测试用例

[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;

}

当通过浏览器在MVC应用程序中执行实际代码时,它工作正常。但是ModelState.IsValid在我的Unit测试中总是返回true并且失败。 后来我明白验证不是由控制器执行的。控制器在验证发生后收到了模型,因此它具有适当的ModelState。 我的问题是我应该为模型验证编写单元测试的方法是什么,还是我应该写它?

2 个答案:

答案 0 :(得分:9)

您可以直接调用该方法并对其结果进行断言。

[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.");
}

答案 1 :(得分:3)

很抱歉急于发布问题。我找到了一种方法here。我修改了测试如下:

[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" } }
    };

    ValidationContext contex = new ValidationContext(model);
    Validator.ValidateObject(model, contex);

}