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
放在控制器内部,并在测试中检查结果。这对我不起作用。是不是因为我的输入是一个带有验证器的类的子类?