C# ModelState.IsValid不验证模型

C# ModelState.IsValid不验证模型,c#,asp.net-mvc-3,C#,Asp.net Mvc 3,我的模型课如下: public class PostInputViewModel { [Required] [MinLength(1)] [MaxLength(125)] public string Title { get; set; } [Required] [AllowHtml] [Display(Name="Content")] public strin

我的模型课如下:

public class PostInputViewModel
    {
        [Required]
        [MinLength(1)]
        [MaxLength(125)]
        public string Title { get; set; }

        [Required]
        [AllowHtml]
        [Display(Name="Content")]
        public string Content { get; set; }
    }
[HttpPost]
        public ActionResult Write(PostInputViewModel input)
        {
            if (!ModelState.IsValid)
                return View(input);

            var post = new Post
            {
                Title = input.Title,
                Content = input.Content,
                DateCreated = DateTime.Now,
                DateModified = DateTime.MaxValue,
            };

            dbContext.Posts.Add(post);
            dbContext.SaveChanges();

            return RedirectToAction("Index", "Home");
        }
[TestMethod]
        public void write_should_validate_model()
        {
            var input = new PostInputViewModel();
            input.Title = null;
            input.Content = null;
            var actionResult = controller.Write(input) as ViewResult;

            Assert.IsFalse(actionResult.ViewData.ModelState.IsValid);
        }
控制器如下所示:

public class PostInputViewModel
    {
        [Required]
        [MinLength(1)]
        [MaxLength(125)]
        public string Title { get; set; }

        [Required]
        [AllowHtml]
        [Display(Name="Content")]
        public string Content { get; set; }
    }
[HttpPost]
        public ActionResult Write(PostInputViewModel input)
        {
            if (!ModelState.IsValid)
                return View(input);

            var post = new Post
            {
                Title = input.Title,
                Content = input.Content,
                DateCreated = DateTime.Now,
                DateModified = DateTime.MaxValue,
            };

            dbContext.Posts.Add(post);
            dbContext.SaveChanges();

            return RedirectToAction("Index", "Home");
        }
[TestMethod]
        public void write_should_validate_model()
        {
            var input = new PostInputViewModel();
            input.Title = null;
            input.Content = null;
            var actionResult = controller.Write(input) as ViewResult;

            Assert.IsFalse(actionResult.ViewData.ModelState.IsValid);
        }
当我通过单击F5运行web应用程序时,如果我没有输入标题和内容值,ModelState.IsValid为false,但是如果我使用单元测试用例测试控制器类,ModelState.IsValid始终为true。测试用例如下所示:

public class PostInputViewModel
    {
        [Required]
        [MinLength(1)]
        [MaxLength(125)]
        public string Title { get; set; }

        [Required]
        [AllowHtml]
        [Display(Name="Content")]
        public string Content { get; set; }
    }
[HttpPost]
        public ActionResult Write(PostInputViewModel input)
        {
            if (!ModelState.IsValid)
                return View(input);

            var post = new Post
            {
                Title = input.Title,
                Content = input.Content,
                DateCreated = DateTime.Now,
                DateModified = DateTime.MaxValue,
            };

            dbContext.Posts.Add(post);
            dbContext.SaveChanges();

            return RedirectToAction("Index", "Home");
        }
[TestMethod]
        public void write_should_validate_model()
        {
            var input = new PostInputViewModel();
            input.Title = null;
            input.Content = null;
            var actionResult = controller.Write(input) as ViewResult;

            Assert.IsFalse(actionResult.ViewData.ModelState.IsValid);
        }
我错过什么了吗?
提前感谢。

控制器中不会发生模型验证。它发生在模型传递给控制器之前

请注意,控制器操作只是“测试”模型是否有效。谁在您的测试用例中验证模型?没什么

您可以使用.NET类进行验证,但是在这种情况下,您将测试.NET验证。这是人们在编写单元测试时经常犯的错误之一。他们测试第三方代码,而不是自己的代码


如果您确实想测试您是否已将正确的验证属性应用于类,那么您可以简单地反映您的类并检查属性上的属性。通过这种方式,您将跳过.NET验证层,并且只有在缺少属性时,测试才会失败。

如果您想让控制器尝试验证模型,可以在断言之前调用
TryValidateModel
方法:

controller.TryValidateModel(input);

但我同意你只需要测试验证属性。不过,这可能没问题;它将验证您的模型是否应用了预期的属性。

验证实际上发生在调用控制器上的Write方法之前,该方法将填充ModelState属性

在我看来,您的单元测试并不是在真正测试控制器(如果您实际上正试图这样做的话)

真正的控制器测试如下所示:

        [TestMethod]
        public void write_should_validate_model()
        {
            controller.ModelState.AddModelError("Title", "Empty"); //These values don't really matter

            var actionResult = controller.Write(new PostInputViewModel()) as ViewResult;

            //Assert that the correct view was returned i.e. Not Home/Index
            //Assert that a new post has not been added to your Mock Repository                
        }

您没有运行初始化控制器的MVC生命周期。我创建控制器实例就像创建普通实例一样,例如PostController controller=new PostController();如果controller需要采用MVC生命周期,那么在测试用例中如何做到这一点?他不是在测试.Net代码;他在测试他的品质。测试的有效性仍有争议。
TryValidateModel
被标记为
protectedinternal
,那么它怎么能这样使用呢?
TryValidateModel
控制器的成员。您的控制器应该继承自
controller
,继承的类可以调用其基类中的任何受保护方法。明白,但这里我们不需要从测试方法调用
TryValidateModel
,在该测试方法中,正在测试的控制器的实例已被实例化?否,您将调用
TryValidateModel
放在控制器内部,并在测试中检查结果。这对我不起作用。是不是因为我的输入是一个带有验证器的类的子类?