13

Como dice el título, estoy buscando instrucciones sobre cómo probar correctamente una extensión de controlador. La extensión hace una vista parcial que a su vez estoy usando dentro de un JsonResult: UsoBuscando dirección en la unidad probando una extensión de controlador que rinde una vista parcial

public static string RenderPartialViewToString(this Controller controller, string viewName = null, object model = null) 
     { 
      if (string.IsNullOrEmpty(viewName)) 
      { 
       viewName = controller.ControllerContext.RouteData.GetRequiredString("action"); 
      } 

      controller.ViewData.Model = model; 

      using (StringWriter sw = new StringWriter()) 
      { 
       ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(controller.ControllerContext, viewName); 
       ViewContext viewContext = new ViewContext(controller.ControllerContext, viewResult.View, controller.ViewData, controller.TempData, sw); 
       viewResult.View.Render(viewContext, sw); 
       return sw.GetStringBuilder().ToString(); 
      } 
     } 

Ejemplo:

public JsonResult Foo() 
{ 
    var model = _repository.getSomeData(); 

    return Json(new { html = this.RenderPartialViewToString("Index", model) }, JsonRequestBehavior.AllowGet); 
} 

estoy usando NUnit & la MvcContrib test helper, sin embargo, cuando la configuración de un controlador que hace uso de esta extensión me estoy ejecutando en un NRE. ¿Asumo que el contexto del controlador no está configurado correctamente?

En última instancia, la prueba está vomitando en ViewEngines.Engines.FindPartialView. Aquí está una parte de la prueba en su defecto:

var routeData = new RouteData(); 
routeData.Values.Add("controller", "someName"); 
routeData.Values.Add("action", "someAction"); 

var builder = new TestControllerBuilder(); 
var controller = new ListingController(repository.Object); 
builder.RouteData = routeData; 
builder.InitializeController(controller); 

var result = controller.Foo(); 

Respuesta

22

Usted tendrá que añadir un motor de vista burlado a la colección ViewEngines.Engines para que pueda burlarse de la llamada FindPartialView. He aquí un ejemplo con la burla de Rhino:

var view = MockRepository.GenerateStub<IView>(); 
var engine = MockRepository.GenerateStub<IViewEngine>(); 
var viewEngineResult = new ViewEngineResult(view, engine); 
engine 
    .Stub(x => x.FindPartialView(null, null, false)) 
    .IgnoreArguments() 
    .Return(viewEngineResult); 
ViewEngines.Engines.Add(engine); 

Posteriormente, se podría afirmar que el método view.Render fue llamado, interceptar sus argumentos y escribir algunos datos burlaron a este escritor y finalmente afirmar que su acción de controlador devuelve esta cadena burlado.

+0

Me di un golpe en la frente y cité el comercial V8. Doh! Gracias por señalar lo obvio que no pude ver. Solo para estar seguro, estoy hablando en serio, no de manera graciosa. –

+0

gracias, usado el mismo enfoque, pero solo con el framework Moq. –

+5

En MVC4, es posible que deba hacer ViewEngines.Engines.Clear() antes de agregar el motor simulado. Al menos eso es lo que tuve que hacer para que esto funcione después de actualizar de MVC3 a MVC4. – antinescience

Cuestiones relacionadas