He estado trabajando en la excelente publicación de Scott Guthrie en ASP.NET MVC Beta 1. En él, muestra las mejoras realizadas en el método UpdateModel y cómo mejoran las pruebas unitarias. He recreado un proyecto similar, pero cada vez que ejecuto un UnitTest que contiene una llamada a UpdateModel, recibo una ArgumentNullException que nombra el parámetro controllerContext.¿Cómo puedo probar las acciones sin simular que utilizan UpdateModel?
He aquí los bits correspondientes, empezando por mi modelo:
public class Country {
public Int32 ID { get; set; }
public String Name { get; set; }
public String Iso3166 { get; set; }
}
La acción del controlador:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(Int32 id, FormCollection form)
{
using (ModelBindingDataContext db = new ModelBindingDataContext()) {
Country country = db.Countries.Where(c => c.CountryID == id).SingleOrDefault();
try {
UpdateModel(country, form);
db.SubmitChanges();
return RedirectToAction("Index");
}
catch {
return View(country);
}
}
}
Y por último, mi unidad de prueba que está fallando:
[TestMethod]
public void Edit()
{
CountryController controller = new CountryController();
FormCollection form = new FormCollection();
form.Add("Name", "Canada");
form.Add("Iso3166", "CA");
var result = controller.Edit(2 /*Canada*/, form) as RedirectToRouteResult;
Assert.IsNotNull(result, "Expected to be redirected on successful POST.");
Assert.AreEqual("Show", result.RouteName, "Expected to redirect to the View action.");
}
ArgumentNullException
se lanza por la llamada al UpdateModel
con el mensaje "El valor no puede ser nulo. P nombre del parámetro: controllerContext ". Supongo que en algún lugar el UpdateModel
requiere el System.Web.Mvc.ControllerContext
que no está presente durante la ejecución de la prueba.
También estoy asumiendo que estoy haciendo algo mal en alguna parte y solo necesito apuntar en la dirección correcta.
Ayuda ¡Por favor!
Estoy de acuerdo, podría resolver esto burlándose, pero eso va explícitamente en contra de lo que Scott dice en su publicación en referencia a los ejemplos de UpdateModel: "No tuvimos que burlarnos de nada para probar los dos escenarios de envío de formularios anteriores. " –
Miré la fuente de TryUpdateModel (que utiliza UpdateModel) y definitivamente usa ControllerContext. Actualicé mi respuesta con el bit de código fuente relevante. – tvanfosson
@Hellfire, vi un comentario en la publicación del blog que indicaba que al menos otra persona estaba teniendo el mismo error. Podría ser que ModelBindingContext cambió antes de que Beta 1 saliera por la puerta. – tvanfosson