2008-11-07 9 views
23

¿Hay alguna manera de (unidad) probar mis propios HtmlHelpers? En caso de que me gustaría tener un control personalizado (representado por HtmlHelper) y conozco los requisitos para ese control, ¿cómo podría escribir pruebas primero y luego escribir el código? ¿Hay alguna manera específica (agradable) de hacer eso?Probando HtmlHelpers en ASP.NET MVC

¿Vale la pena?

Respuesta

30

El problema principal es que tiene que burlarse del HtmlHelper porque puede estar utilizando métodos del helper para obtener rutas o valores o devolver el resultado de otro método de extensión. La clase HtmlHelper tiene bastantes propiedades y algunas bastante complejas como ViewContext o el Controlador actual.

This post from Ben Hart que explica cómo crear dicho simulacro con Moq. Se puede traducir fácilmente a otro marco simulado.

Esta es mi versión de Rhino Mocks adaptada a los cambios en el Marco MVC. No está completamente probado, pero que está funcionando para mí, pero no esperamos un resultado perfecto:

public static HtmlHelper CreateHtmlHelper(ViewDataDictionary viewData) 
    { 
     var mocks = new MockRepository(); 

     var cc = mocks.DynamicMock<ControllerContext>(
      mocks.DynamicMock<HttpContextBase>(), 
      new RouteData(), 
      mocks.DynamicMock<ControllerBase>()); 

     var mockViewContext = mocks.DynamicMock<ViewContext>(
      cc, 
      mocks.DynamicMock<IView>(), 
      viewData, 
      new TempDataDictionary()); 

     var mockViewDataContainer = mocks.DynamicMock<IViewDataContainer>(); 

     mockViewDataContainer.Expect(v => v.ViewData).Return(viewData); 

     return new HtmlHelper(mockViewContext, mockViewDataContainer); 
    } 
+2

lamentablemente los errores de entrada de blog, pero el anterior explica muy bien lo que tiene que hacer – MJJames

+1

parece que han cambiado el MV C marco ligeramente ya que el anterior como ViewContext ahora también toma un TextWriter –

+4

Esto es muy útil, pero probando contra MVC3 Tuve que modificar esto agregando un nuevo parámetro al mockViewContextConstructor (utilicé 'TextWriter.Null') y en lugar del mockViewDataContainer, tuve que establecer ViewData explícitamente (por ejemplo, 'mockViewDataContainer.ViewData = viewData;') o Rhino Mocks lanza una excepción. –

0

Estoy creando un ayudante de encargo, y este es el código que estoy usando para burlarse de la httphelper con Moq y ASP MVC 2. También paso como parámetro un simulacro de HttpRequestBase. Puede quitar que si no lo necesita

 
public static HtmlHelper CreateHtmlHelper(ViewDataDictionary viewData, Mock requestMock) 
     { 
      var contextBaseMock = new Mock(); 
      contextBaseMock.SetupGet(cb => cb.Request).Returns(requestMock.Object); 

      var cc = new ControllerContext(contextBaseMock.Object, 
              new RouteData(), 
              new Mock().Object); 
      var vctx = new ViewContext(
       cc, 
       new Mock().Object, 
       viewData, 
       new TempDataDictionary(), 
       new HtmlTextWriter(new StreamWriter(new MemoryStream()))); 

      var mockViewDataContainer = new Mock(); 

      mockViewDataContainer.SetupGet(v => v.ViewData).Returns(viewData); 

      return new HtmlHelper(vctx, mockViewDataContainer.Object); 
     } 
9

Si alguien está buscando la forma de crear HtmlHelper<T> (eso es lo que buscaba), aquí es una aplicación que podría ayudar - mi tipo es un modelo de clase llamada :

public static HtmlHelper<Model> CreateHtmlHelper() 
{ 
    ViewDataDictionary vd = new ViewDataDictionary(new Model()); 

    var controllerContext = new ControllerContext(new Mock<HttpContextBase>().Object, 
                new RouteData(), 
                new Mock<ControllerBase>().Object); 

    var viewContext = new ViewContext(controllerContext, new Mock<IView>().Object, vd, new TempDataDictionary(), new Mock<TextWriter>().Object); 

    var mockViewDataContainer = new Mock<IViewDataContainer>(); 
    mockViewDataContainer.Setup(v => v.ViewData).Returns(vd); 

    return new HtmlHelper<Model>(viewContext, mockViewDataContainer.Object); 
} 

O una aplicación más genérica:

public HtmlHelper<T> CreateHtmlHelper<T>() where T : new() 
    { 
     var vd = new ViewDataDictionary(new T()); 

     var controllerContext = new ControllerContext(new Mock<HttpContextBase>().Object, 
                 new RouteData(), 
                 new Mock<ControllerBase>().Object); 

     var viewContext = new ViewContext(controllerContext, new Mock<IView>().Object, vd, new TempDataDictionary(), new Mock<TextWriter>().Object); 

     var mockViewDataContainer = new Mock<IViewDataContainer>(); 
     mockViewDataContainer.Setup(v => v.ViewData).Returns(vd); 

     return new HtmlHelper<T>(viewContext, mockViewDataContainer.Object); 
    }