13

Come dice il titolo, sto cercando indicazioni su come testare correttamente un'estensione del controller. L'estensione rende una vista parziale che a sua volta sto utilizzando in un JsonResult: UtilizzoCercare la direzione sull'unità che verifica un'estensione del controller che esegue il rendering di una vista parziale

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(); 
      } 
     } 

Esempio:

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

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

Sto utilizzando NUnit & il MvcContrib test helper, tuttavia quando si imposta un controller che fa uso di questa estensione sto correndo in un NRE. Suppongo che il contesto del controller non sia configurato correttamente?

In definitiva il test è su ViewEngines.Engines.FindPartialView. Ecco una parte del test in mancanza:

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(); 

risposta

22

Si dovrà aggiungere un motore di visualizzazione deriso alla raccolta ViewEngines.Engines modo che si può prendere in giro la chiamata FindPartialView. Ecco un esempio con Rhino Mocks:

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); 

Poi si potrebbe affermare che il metodo view.Render è stato chiamato, intercettare i suoi argomenti e scrivere alcuni dati deriso a questo scrittore e, infine, affermare che la vostra azione di controllo è tornato questa stringa deriso.

+0

Mi sono appena schiaffeggiato sulla fronte e ho citato lo spot V8. Doh! Grazie per aver sottolineato l'ovvio che non ho potuto vedere. Solo per essere sicuro, sono serio, non faceto. –

+0

grazie, stesso approccio, ma solo con framework Moq. –

+5

In MVC4, potrebbe essere necessario fare ViewEngines.Engines.Clear() prima di aggiungere il motore fittizio. Almeno questo è quello che dovevo fare per farlo funzionare dopo l'aggiornamento da MVC3 a MVC4. – antinescience

Problemi correlati