Unit tests on MVC validation
asp.net-mvc, asp.net-mvc-2, tdd, unit-testing, validation
Solution
Instead of passing in a `BlogPost` you can also declare the actions parameter as `FormCollection`. Then you can create the `BlogPost` yourself and call `UpdateModel(model, formCollection.ToValueProvider());`.
This will trigger the validation for any field in the `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);
}
Just make sure your test adds a null value for every field in the views form that you want to leave empty.
I found that doing it this way, at the expense of a few extra lines of code, makes my unit tests resemble the way the code gets called at runtime more closely making them more valuable. Also you can test what happens when someone enters "abc" in a control bound to an int property.
Problem
How can I test that my controller action is putting the correct errors in the ModelState when validating an entity, when I'm using DataAnnotation validation in MVC 2 Preview 1? Some code to illustrate. First, the action: ``` [HttpPost] public ActionResult Index(BlogPost b) { if(ModelState.IsValid) { _blogService.Insert(b); return(View("Success", b)); } return View(b); } ``` And here's a failing unit test that I think should be passing but isn't (using 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); } ``` I guess in addition to this question, should I be testing validation, and should I be testing it in this way?