Bien, entonces estoy usando MVCContrib TestHelper para probar mis controladores, lo cual funciona muy bien.Agregue claves y valores a RouteData cuando use MVCContrib para probar los controladores MVC 3 y las Vistas
Como mucha gente, me refiero a la prueba de integración aquí y quiero al menos asegurarme de que mis vistas se rendericen sin error dado el modelo proporcionado ... de lo contrario, puedo perder toda una clase de errores básicamente relacionados al modelo a pesar de que estoy probando el controlador (como la vista no representa si la propiedad del modelo es nula).
De todas formas, comencé a tratar de encontrar la manera de hacer esto (también conocido como googlear cómo hacerlo). Parecía que la forma más fácil era construir un HTMLHelper y hacer que solo representara las vistas (parcial en este caso).
Desafortunadamente, cuando trato de usar mi HTMLHelper burlado, se queja de que no tiene el nombre del controlador disponible en los datos de la ruta.
Efectivamente, miro y los controladores RouteData no están completos. Lamentablemente, los RouteData.Values RouteValueDictionary son de solo lectura, por lo que no puedo proporcionar los valores necesarios.
No estoy casado con la idea de HTMLHelper para resolver el problema de representar la vista como parte de la prueba, así que siéntase libre de sugerir alternativas allí, pero no se moleste en sugerir probar mis Vistas usando Selenio, Watin u otras herramientas de prueba de UI ... Quiero que el control pueda hacer cosas como manipular y restaurar información de estado y datos para algunas de las pruebas, lo que no puedo hacer con las pruebas basadas en UI.
Aquí está el código que estoy usando actualmente para tratar de hacer que 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í es 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 recibo es: RouteData debe contener un elemento denominado 'controlador' con un valor de cadena no vacío.
Funciona muy bien, gracias. Por supuesto, ahora tengo que encontrar la forma de resolver la ruta de acceso a las vistas porque obtengo los errores "La ruta virtual relativa de la aplicación no se puede convertir en absoluta", pero esta parte funcionaba al menos. – Amasuriel