Thursday, July 23, 2009

UpdateModel Unit Testing Gotcha!

If you’re unit testing and make a call to UpdateModel, you get the case where your object doesn’t get updated.

Say your controller has an Edit Post action similar to:

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(Customer customer)
{
Customer _customer = repository.GetByKey(customer.CustomerKey);
UpdateModel(_customer);
repository.Save();
return RedirectToAction("Index");
}
Now you might think that the call to UpdateModel will use your the object you passed in. Wrong! It wants the form values that get passed as part of the post request. So if you’re unit testing and using MVC fakes, you need to pass in some form values.
Customer customer = new Customer()
{
CustomerKey = 1234,
CustomerName = "ABC Siding",
Address = "1 Main",
City = "Springfield",
State = "IL",
ZipCode = "62701",
FirstName = "Fred",
LastName = "Jones",
Phone = "2175551212",
Fax = "2175551213",
IsActive = true
};

NameValueCollection formParams = new NameValueCollection {
{ "CustomerName", customer.CustomerName },
{ "Address", customer.Address },
{ "City", customer.City },
{ "State", customer.State },
{ "ZipCode", customer.ZipCode },
{ "FirstName", customer.FirstName },
{ "LastName", customer.LastName },
{ "Phone", customer.Phone },
{ "Fax", customer.Fax },
{ "IsActive", customer.IsActive.ToString() }
};

target.ControllerContext = new FakeControllerContext(
target, "PaulBrown", new string[] { ApplicationRoles.ViewCustomersGroup },
null, formParams, null, null, null);
Once you pass in the form vars, everything works fine. Now the question I’m asking myself is why I’ve got an argument in the method signature at all. The answer is because that was how Scott Gu did it in NerdDinner. Gonna have to look at that!

No comments: