ASP.NET MVC控制器后方法单元测试:ModelState.IsValid始终为true [英] ASP.NET MVC Controller post method unit test: ModelState.IsValid always true
问题描述
我已经为ASP.NET MVC Web应用程序编写了第一个单元测试.一切正常,它为我提供了有价值的信息,但是我无法测试视图模型中的错误.即使未填写某些值(空字符串或null),ModelState.IsValid始终为true.
I have written my first unit tests for an ASP.NET MVC web application. All works fine and it is giving me valuable information, but I can't test errors in the view model. The ModelState.IsValid is always true, even when some values are not filled in (empty string or null).
我已经阅读了将发布的数据映射到模型时进行模型验证的过程,您需要编写一些代码亲自进行模型验证:
I have read already that the model validation happens when the posted data is mapped to the model and you need to write some code to do the model verification yourself:
- Geek With Blogs
- so: How can U test ModelState?
我尝试了链接网页中提供的三个示例,但似乎对我不起作用.
I have tried the three examples provided in the linked webpages, but it seems not to work for me.
某些代码:
我的视图模型
...
[Required(ErrorMessageResourceName = "ErrorFirstName", ErrorMessageResourceType = typeof(Mui))]
[MaxLength(50)]
[Display(Name = "Firstname", ResourceType = typeof(Mui))]
public string FirstName { get; set; }
...
控制器
...
[HttpPost]
public ActionResult Index(POSViewModel model)
{
Contract contract = contractService.GetContract(model.ContractGuid.Value);
if (!contract.IsDirectDebit.ToSafe())
{
ModelState.Remove("BankName");
ModelState.Remove("BankAddress");
ModelState.Remove("BankZip");
ModelState.Remove("BankCity");
ModelState.Remove("AccountNr");
}
if (ModelState.IsValid)
{
...
contractValidationService.Create(contractValidation);
unitOfWork.SaveChanges();
return RedirectToAction("index","thanks");
}
else
{
return Index(model.ContractGuid.ToString());
}
}
我的单元测试
posViewModel.FirstName = null;
posViewModel.LastName = "";
...
var modelBinder = new ModelBindingContext()
{
ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(() => posViewModel, posViewModel.GetType()),
ValueProvider = new NameValueCollectionValueProvider(new System.Collections.Specialized.NameValueCollection(), CultureInfo.InvariantCulture)
};
var binder = new DefaultModelBinder().BindModel(new ControllerContext(), modelBinder);
posController.ModelState.Clear();
posController.ModelState.Merge(modelBinder.ModelState);
ActionResult result = posController.Index(posViewModel);
//Assert
mockContractValidationService.Verify(m => m.Create(It.IsAny<ContractValidation>()), Times.Never);
Assert.IsInstanceOfType(result, typeof(ViewResult));
在视图上,我使用的是无干扰的JavaScript验证,并且可以正常工作.
On the view, I'm using unobtrusive JavaScript validation, and it works.
推荐答案
I found this solution: SO: Validation does not work when I use Validator.TryValidateObject combined with the solution @Kenneth provided:
[TestMethod]
public void test_validation()
{
var sut = new POSViewModel();
// Set some properties here
var context = new ValidationContext(sut, null, null);
var results = new List<ValidationResult>();
TypeDescriptor.AddProviderTransparent(new AssociatedMetadataTypeTypeDescriptionProvider(typeof(POSViewModel), typeof(POSViewModel)), typeof(POSViewModel));
var isModelStateValid = Validator.TryValidateObject(sut, context, results, true);
// Assert here
}
如果您拥有一个包含所有资源的类库,请不要忘记在测试项目中引用它.
If you have a class library with all you resources in, don't forget to reference it in your test project.
这篇关于ASP.NET MVC控制器后方法单元测试:ModelState.IsValid始终为true的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!