Bueno por lo que estoy usando MVCContrib TestHelper a prueba la unidad de mi controladores, que funciona muy bien.

Al igual que muchas personas a pesar de que, por unidad de prueba de que realmente significa la integración de la prueba aquí y quiero al menos asegúrese de que mis puntos de vista render sin error dado el modelo de…de lo contrario puede perder toda una clase de errores relacionados básicamente con el modelo a pesar de que yo estoy probando el controlador como en la vista no la representación si un modelo de propiedad es null).

De todos modos empecé tratando de averiguar cómo hacer esto (también conocido como buscar en google cómo hacerlo). Parecía que la manera más fácil era construir un HTMLHelper y tienen sólo representar los puntos de vista (parcial, en este caso).

Lamentablemente cuando trato de usar mi se burlaban de HTMLHelper se queja de que no tiene el nombre del controlador disponible en la ruta de datos.

Bastante seguro, yo lo miro y los controladores de RouteData no se rellena. Por desgracia, la RouteData.Los valores RouteValueDictionary es de sólo lectura, por lo que no puedo sólo el suministro de los valores necesarios.

No estoy casado con la HTMLHelper idea para resolver el problema de la realidad en la representación de la vista como parte de la prueba, así que siéntase libre de sugerir alternativas hay, pero por favor, no te molestes en sugiriendo que prueba mi punto de vista el uso de Selenio, Watin u otra prueba de interfaz de usuario herramientas…quiero que el control sea capaz de hacer cosas como manipular y restaurar el estado y los datos de algunas de las pruebas, que no puedo hacer con la interfaz de usuario basada en pruebas.

Aquí es el código que estoy utilizando actualmente para tratar de mostrar el parcial:

    public class FakeView : IView
{
    #region IView Members
    public void Render(ViewContext viewContext, System.IO.TextWriter writer)
    {
        throw new NotImplementedException();
    }
    #endregion
}

public class WebTestUtilities
{
    public static void prepareCache()
    {
        SeedDataManager seed = new SeedDataManager();
        seed.CheckSeedDataStatus();
    }

    public static string RenderRazorViewToString(string viewName, object model, Controller controller)
    {
        var sb = new StringBuilder();
        var memWriter = new StringWriter(sb);
        var html = new HtmlHelper(new ViewContext(controller.ControllerContext,
            new FakeView(), new ViewDataDictionary(), new TempDataDictionary(), memWriter),
            new ViewPage());
        //This fails because it can't extract route information like the controller name)
        html.RenderPartial(viewName, model);
        return sb.ToString();
    }


    public void setupTestEnvironment(Controller controller)
    {
        RouteTable.Routes.Clear();
        RouteTable.Routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        RouteTable.Routes.MapRoute(
            "Default", 
            "{controller}/{action}/{id}", 
            new { controller = "Main", action = "DefaultView", id = UrlParameter.Optional } 
        );




        ModelBinders.Binders[typeof(DateTime)] = new DateTimeModelBinder();
        ModelBinders.Binders[typeof(DateTime?)] = new DateTimeModelBinder();
        ModelMetadataProviders.Current = new DateTimeMetadataProvider();



    }
}

Y aquí está mi método de prueba:

        [TestMethod]
    public void GetUserTableView()
    {
        ViewResult result = controller.UserTable() as ViewResult;

        //I can populate the route and handler on the controller...
        RouteData routes = RouteTable.Routes.GetRouteData(controller.HttpContext);
        controller.RouteData.Route = routes.Route;
        controller.RouteData.RouteHandler = routes.RouteHandler;
        RouteValueDictionary routeKeys = new RouteValueDictionary();
        routeKeys.Add("controller", "UserManagement");
        routeKeys.Add("action", "UserTable");
        //But the RouteData.Values collection is read only :(
        controller.RouteData = new RouteData(){Values = routeKeys};
        string renderedView = WebTestUtilities.RenderRazorViewToString(result.ViewName, result.Model, controller);
    }

Por CIERTO, el error específico que se obtiene es :
El RouteData debe contener un elemento llamado ‘controller’ con un no-valor de cadena vacía.

OriginalEl autor Amasuriel | 2012-03-22

2 Comentarios

  1. 29

    Puede que ya han trabajado en esto, pero tuve un problema similar y resuelto configuración de la RouteData por el restablecimiento de la ControllerContext en el controlador así:

    RouteData routeData = new RouteData();
    routeData.Values.Add("someRouteDataProperty", "someValue");
    ControllerContext controllerContext = new ControllerContext { RouteData = routeData };
    controller.ControllerContext = controllerContext;

    y, a continuación, en el controlador de RouteData.Valores.ContainsKey(«someRouteDataProperty») funciona como se haya configurado en la prueba.

    Esto funciona porque hay un constructor sin parámetros de la ControllerContext que deliberadamente no permitir burlas etc.

    Funciona muy bien, gracias. Por supuesto, ahora tengo que averiguar cómo resolver la ruta de acceso a los puntos de vista porque me sale «La aplicación relativa ruta de acceso virtual no puede ser absoluta» de errores, pero esta parte han trabajado al menos.

    OriginalEl autor stevie_c

  2. 2

    Puede reemplazar los Controladores de ControllerContext.RouteData – su virtual y RouteData propiedad es sólo la utilizan para leer.

    Desde el reflejo del código de asp.net mvc RouteData propiedad:

    public RouteData RouteData 
    { 
        get 
        {
            return ControllerContext == null ? null : ControllerContext.RouteData; 
        }
    }
    Pero entonces tengo que usar una versión modificada de la clase controlador que yo no quiero.
    No, usted NO lo necesita

    OriginalEl autor Sly

Dejar respuesta

Please enter your comment!
Please enter your name here