2009-04-05 16 views
25

Estoy haciendo algunas pruebas sencillas de unidad de MS en mi controlador estándar, nada especial.¿La unidad de prueba de los resultados de mi método de controlador en un ViewName vacío?

Cuando miro la propiedad ViewName, desde el objeto devuelto ViewResult, es "" (vacío).

estoy bajo la impresión de que la ViewName está implicada por el nombre de la View (como suggested by this MS article en pruebas controlador ASP.NET MVC).

Por cierto, cuando pruebo ViewData, está todo allí y es correcto.

Aquí está el código que tengo ...

public ActionResult Index(int? page, string tag) 
{ 
    if (page == null || page <= 0) 
    { 
     page = 1; 
    } 

    var viewData = new IndexViewData 
         { 
         ... my property setters, etc ... 
         }; 
    return View(viewData); 
} 

[TestMethod] 
public void Index_Action_Should_Return_Index_View_For_Default_HomePage() 
{ 
    // Arrange. 
    var controller = PostController; // Wrapper, cause I use D.I. 

    // Act. 
    ViewResult viewResult = controller.Index(null, null) as ViewResult; 

    // Assert. 
    Assert.IsNotNull(viewResult); 
    Assert.AreEqual("Index", viewResult.ViewName); // This is false/fails. 

    var indexViewData = viewResult.ViewData.Model as IndexViewData; 
    Assert.IsNotNull(indexViewData); // This is true. 
} 

Respuesta

27

El ViewName sólo está presente cuando la coloque en el ViewResult. Si el nombre de su Vista coincide con el nombre de su controlador, entonces verificaría que ViewName sea nulo o esté vacío ya que eso sería (IMO) el comportamiento correcto ya que no desea establecer un nombre en la vista. Solo compruebo que ViewName está configurado cuando intento que la Vista que se va a devolver no coincida con la acción, por ejemplo, al devolver la vista "Error".

EDIT: La siguiente es la fuente de ExecuteResult en ViewResultBase.cs (desde RC1, no tengo la fuente para RTW en mi Macintosh). Como puede ver, comprueba si ViewName se ha configurado directamente y, de no ser así, lo saca de la acción en los datos de ruta del contexto del controlador. Esto solo ocurre en ExecuteResult, que se invoca DESPUÉS de que se haya completado la acción de su controlador.

public override void ExecuteResult(ControllerContext context) { 
     if (context == null) { 
      throw new ArgumentNullException("context"); 
     } 
     if (String.IsNullOrEmpty(ViewName)) { 
      ViewName = context.RouteData.GetRequiredString("action"); 
     } 

     ViewEngineResult result = null; 

     if (View == null) { 
      result = FindView(context); 
      View = result.View; 
     } 

     ViewContext viewContext = new ViewContext(context, View, ViewData, TempData); 
     View.Render(viewContext, context.HttpContext.Response.Output); 

     if (result != null) { 
      result.ViewEngine.ReleaseView(context, View); 
     } 
    } 
+0

Heya. Hmm. no entiendo lo que estás diciendo "ViewName solo está presente cuando lo configura en ViewResult". Pensé que el marco automático establece esto? ¿Estás diciendo que no está configurado automáticamente? –

+0

No. Por lo que puedo decir, ViewName es nulo a menos que lo establezcas específicamente. Creo que si es nulo o está vacío, saca el nombre de vista del nombre de la acción. – tvanfosson

+0

>> Creo que si es nulo o está vacío, saca el nombre de la vista del nombre de la acción. << Hmm ... así que eso significa que no debería ser nulo, ¿verdad? –

0

El marco de trabajo establece automáticamente viewname. Pero cuando hacemos una prueba unitaria, cortocircuitamos el marco y no queda nada para establecer el nombre.

Por lo tanto, nuestras acciones deben establecer el nombre de vista de forma explícita cuando realizamos la prueba unitaria. También podríamos verificar nulo o vacío si realmente queremos apoyarnos en la convención.

2

Personalmente encontré que las instalaciones de prueba proporcionadas por MVC2 eran algo torpes. Supongo que ya existe algo mejor, pero terminé creando una clase simple para probar acciones. Modelé la interfaz (la implementación es otra historia) en una clase proporcionada por la excelente fuente abierta Java MVC framework Stripes llamada MockRoundTrip.

Este es el método utilizado para obtener la página de destino de acción al probar acciones, llamado getTripDestination(). Se devuelve el resultado correcto, independientemente de si el nombredevista se establece explícitamente o no

//Get the destination page of the request, using Runtime execution pattern of MVC, namely 
    //if no ViewName is explicitly set in controller, ViewResult will have an empty ViewName 
    //Instead, current action name will be used in its place 
    public string getTripDestination() 
    { 
     RouteData routeData = getRouteData(); 
     ViewResult viewResult = (result is ViewResult) ? (ViewResult)result : null; 
     string tripDestination = (viewResult != null) ? viewResult.ViewName : ""; 

     return (tripDestination != "") ? tripDestination : (String)routeData.Values["action"]; 
    } 

    private RouteData getRouteData() 
    { 
     HttpContextBase context = controller.ControllerContext.RequestContext.HttpContext; 
     return RouteTable.Routes.GetRouteData(context); 
    } 
0

Los documentation for Controller.View() estados:

Esta sobrecarga método de la clase View devuelve un objeto ViewResult que tiene un ViewName vacía propiedad. Si está escribiendo pruebas unitarias para las acciones del controlador , tenga en cuenta la propiedad ViewName vacía para las pruebas de unidad que no toman el nombre de una vista de cadena.

En tiempo de ejecución, si la propiedad ViewName está vacía, se usa el nombre de acción actual en lugar de la propiedad ViewName.

Así que cuando esperamos una vista con el mismo nombre que la acción actual, podemos probar que se trata de una cadena vacía.

Alternativamente, el método Controller.View (String) establecerá ViewName.

Cuestiones relacionadas