当我在MVC2Preview1中使用DataAnnotation验证时,如何测试我的控制器操作在验证实体时是否在ModelState中放置了正确的错误?
一些代码来说明。首先,动作:
[HttpPost]
public ActionResult Index(BlogPost b)
{
if(ModelState.IsValid)
{
_blogService.Insert(b);
return(View("Success", b));
}
return View(b);
}
这是一个失败的单元测试,我认为它应该通过,但没有通过(使用MbUnit & Moq):
[Test]
public void When_processing_invalid_post_HomeControllerModelState_should_have_at_least_one_error()
{
// arrange
var mockRepository = new Mock<IBlogPostSVC>();
var homeController = new HomeController(mockRepository.Object);
// act
var p = new BlogPost { Title = "test" }; // date and content should be required
homeController.Index(p);
// assert
Assert.IsTrue(!homeController.ModelState.IsValid);
}
我想除了这个问题之外,我是否应该测试验证,我应该以这种方式测试它吗?
发布于 2009-08-13 07:32:09
您也可以将BlogPost
参数声明为FormCollection
,而不是传入actions。然后,您可以自己创建BlogPost
并调用UpdateModel(model, formCollection.ToValueProvider());
。
这将触发对FormCollection
中任何字段的验证。
[HttpPost]
public ActionResult Index(FormCollection form)
{
var b = new BlogPost();
TryUpdateModel(model, form.ToValueProvider());
if (ModelState.IsValid)
{
_blogService.Insert(b);
return (View("Success", b));
}
return View(b);
}
只需确保您的测试为视图表单中您希望保留为空的每个字段添加一个空值。
我发现这样做,以几行额外的代码为代价,使我的单元测试类似于代码在运行时被调用的方式,从而使它们更有价值。您还可以测试当有人在绑定到int属性的控件中输入"abc“时会发生什么。
发布于 2010-07-28 21:08:09
我也遇到了同样的问题,在阅读了Paul的回答和评论后,我寻找了一种手动验证视图模型的方法。
我找到了this tutorial,它解释了如何手动验证使用DataAnnotations的ViewModel。关键代码片段在文章的末尾。
我稍微修改了一下代码--在本教程中省略了TryValidateObject的第四个参数(validateAllProperties)。为了验证所有的注解,应该将其设置为true。
此外,我将代码重构为一个泛型方法,以使ViewModel验证的测试变得简单:
public static void ValidateViewModel<TViewModel, TController>(this TController controller, TViewModel viewModelToValidate)
where TController : ApiController
{
var validationContext = new ValidationContext(viewModelToValidate, null, null);
var validationResults = new List<ValidationResult>();
Validator.TryValidateObject(viewModelToValidate, validationContext, validationResults, true);
foreach (var validationResult in validationResults)
{
controller.ModelState.AddModelError(validationResult.MemberNames.FirstOrDefault() ?? string.Empty, validationResult.ErrorMessage);
}
}
到目前为止,这对我们来说工作得很好。
发布于 2009-08-13 03:58:12
当您在测试中调用homeController.Index方法时,您没有使用任何触发验证的MVC框架,因此ModelState.IsValid始终为真。在我们的代码中,我们直接在控制器中调用助手验证方法,而不是使用环境验证。我没有太多使用DataAnnotations (我们使用NHibernate.Validators)的经验,也许其他人可以提供如何在你的控制器中调用Validate的指导。
https://stackoverflow.com/questions/1269713
复制相似问题