控制器的原因.UpdateModel不会用单元测试的全球化验证属性来验证模型
本文关键字:验证 属性 全球化 模型 单元测试 UpdateModel 控制器 | 更新日期: 2023-09-27 17:51:07
我创建了一个ASP。. NET MVC 5应用程序,使用以下模型类在其Email属性上使用全球化的 Required validation属性:
public class Person
{
[Required(ErrorMessageResourceType = typeof(Resources),
ErrorMessageResourceName = "EmptyEmailError")]
public string Email { get; set; }
}
PersonController类的Create POST动作方法是:
[HttpPost]
public ActionResult Create(FormCollection formData)
{
Person newPerson = new Person();
UpdateModel(newPerson, formData);
if (ModelState.IsValid) {
// code to create the new person
return View("Index", newPerson);
}
else {
return View();
}
}
验证没有创建具有空电子邮件地址的人的测试用例是:
[TestMethod]
void Create_DoesNotCreatePerson_WhenEmailIsEmpty()
{
// arrange
FormCollection person = new FormCollection() { { "Email", string.Empty } };
PersonController controller = new PersonController();
controller.ControllerContext = new ControllerContext();
// act
controller.Create(person);
// assert
Assert.IsFalse(controller.ModelState.IsValid);
}
有了这段代码,正常的执行工作得很好。但是,测试没有通过,这意味着UpdateModel
返回true
,因此没有正确验证人员模型。TryUpdateModel
方法也不起作用
但是如果我从Person类的Required验证属性中删除ErrorMessage参数(即保留它为[Required]),则测试通过。
所以我不知道为什么当我从测试用例调用Create动作方法时,UpdateModel
不验证全球化的Person模型。
我很高兴看到你正在为你的代码编写单元测试:)
首先,你为什么不直接通过Person
,你真的需要FormCollection
吗?
[TestMethod]
void Create_DoesNotCreatePerson_WhenEmailIsEmpty()
{
// arrange
FormCollection person = new FormCollection() { { "Email", string.Empty } };
PersonController controller = new PersonController();
controller.ControllerContext = new ControllerContext();
// third, you might need to add this (haven't tested this)
controller.ModelState.AddModelError("Email", "fakeError");
// act
controller.Create(person);
// assert
Assert.IsFalse(controller.ModelState.IsValid);
}
第四个也是最重要的。我认为你不应该这样测试。您需要针对不同的场景测试结果。这意味着您需要测试方法的返回值。当你说Assert.IsFalse(controller.ModelState.IsValid);
时,你基本上是在说你不相信微软的代码,你想测试他们的代码。我可以向你保证他们的代码有单元测试,你不需要再测试了;)
应该测试从操作结果返回什么视图和返回什么对象。这里有一篇关于如何对此进行单元测试的完整文章-> https://msdn.microsoft.com/en-us/library/gg416511(VS.98).aspx(参见"为检索联系人创建测试")。希望这对你有帮助!
编辑(回复评论):
很抱歉响应时间过长。
我移到了"second"
如果你想测试真正的产品代码,你想做集成测试,而不是单元测试。如果单元测试是您想要的,我建议您遵循我的解决方案建议,否则创建集成测试。我不知道如何说服你,但我已经试过了,所以多读一些资料,我想你会同意在这种情况下如何进行单元测试:)
祝你好运!