Issue
I am using DataAnnotations for my model validation i.e.
[Required(ErrorMessage="Please enter a name")]
public string Name { get; set; }
In my controller, I am checking the value of ModelState. This is correctly returning false for invalid model data posted from my view.
However, when executing the unit test of my controller action, ModelState always returns true:
[TestMethod]
public void Submitting_Empty_Shipping_Details_Displays_Default_View_With_Error()
{
// Arrange
CartController controller = new CartController(null, null);
Cart cart = new Cart();
cart.AddItem(new Product(), 1);
// Act
var result = controller.CheckOut(cart, new ShippingDetails() { Name = "" });
// Assert
Assert.IsTrue(string.IsNullOrEmpty(result.ViewName));
Assert.IsFalse(result.ViewData.ModelState.IsValid);
}
Do I need to do anything extra to set up the model validation in my tests?
Solution
Validation will be performed by the ModelBinder
. In the example, you construct the ShippingDetails
yourself, which will skip the ModelBinder
and thus, validation entirely. Note the difference between input validation and model validation. Input validation is to make sure the user provided some data, given he had the chance to do so. If you provide a form without the associated field, the associated validator won’t be invoked.
There have been changes in MVC2 on model validation vs. input validation, so the exact behaviour depends on the version you are using. See http://bradwilson.typepad.com/blog/2010/01/input-validation-vs-model-validation-in-aspnet-mvc.html for details on this regarding both MVC and MVC 2.
[EDIT] I guess the cleanest solution to this is to call UpdateModel
on the Controller manually when testing by providing a custom mock ValueProvider
. That should fire validation and set the ModelState
correctly.
Answered By – mnemosyn
Answer Checked By – Pedro (BugsFixing Volunteer)