2010-03-22 28 views
30

¿Alguien podría mostrarme cómo harías para crear un HTML Helper simulado con Moq?Cómo probar la unidad HtmlHelper con Moq?

Este article tiene un enlace a un artículo que afirmaba para describir esto, pero siguiendo el enlace sólo se devuelve un error de tiempo de ejecución ASP.NET

[editar] he hecho una pregunta más específica relacionada con el mismo tema here, pero no ha recibido ninguna respuesta. Pensé que era demasiado específico, así que pensé que podría obtener una respuesta más general a una pregunta más general y modificarla para cumplir con mis requisitos.

Gracias

+0

¿Puede dar algunos de los códigos ¿bajo prueba? –

+0

@Samuel, el código relevante está en la pregunta a la que me he vinculado en mi edición. – DaveDev

+0

En realidad, no conozco una buena respuesta (realmente no recuerdo los detalles de C#), pero la superé en un intento de llamar la atención =) –

Respuesta

10

Lo que puede hacer es lo siguiente:

HtmlHelper helper = null; 
helper.YourHelperMethod(); 

n Necesito burlarme de cualquier cosa. Funciona genial para mi

+28

Esto solo funciona si has escrito un método de ayuda que obviamente no usa el helper. Si intenta acceder al 'ViewContext',' RouteCollection', o cualquier otra cosa, esto no lo ayudará. –

+3

Esta no debería ser la respuesta aceptada. Solo responde un solo escenario y no es el caso de que tengas que usar Html Helper. Al igual que @MattEnright dijo, no será de ayuda si necesitas usar prueba de Html Helper para generar Action Link, por ejemplo. –

+1

Esto es obviamente una respuesta burlada -) – trailmax

41

Here 's otro artículo que le muestra cómo lograr lo mismo:

public static HtmlHelper CreateHtmlHelper(ViewDataDictionary vd) 
{ 
    var mockViewContext = new Mock<ViewContext>(
    new ControllerContext(
     new Mock<HttpContextBase>().Object, 
     new RouteData(), 
     new Mock<ControllerBase>().Object), 
    new Mock<IView>().Object, 
    vd, 
    new TempDataDictionary()); 

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

    return new HtmlHelper(mockViewContext.Object, mockViewDataContainer.Object); 
} 
+5

Esta debería ser la respuesta aceptada. El objeto es realmente burlado aquí. – SandRock

+2

Este código solo funciona para MVC4 y no para MVC5. –

+1

Hice un cambio para MVC5. Esperando revisión por pares. – bradlis7

18

En MVC5, el ViewContext tiene un parámetro de constructor adicional para TextWriter, por lo que el código de Thomas ya no funciona. He añadido un TextWriter en memoria de solucionar este problema:

public static HtmlHelper CreateHtmlHelper(ViewDataDictionary vd) 
{ 
    Mock<ViewContext> mockViewContext = new Mock<ViewContext>(
     new ControllerContext(
      new Mock<HttpContextBase>().Object, 
      new RouteData(), 
      new Mock<ControllerBase>().Object 
     ), 
     new Mock<IView>().Object, 
     vd, 
     new TempDataDictionary(), 
     new StreamWriter(new MemoryStream()) 
    ); 

    Mock<IViewDataContainer> mockDataContainer = new Mock<IViewDataContainer>(); 
    mockDataContainer.Setup(c => c.ViewData).Returns(vd); 

    return new HtmlHelper(mockViewContext.Object, mockDataContainer.Object); 
} 
+2

MVC4 también necesita esta versión del código – John

+0

Para usar ViewBag cambié la firma del método a 'static HtmlHelper CreateHtmlHelper estático (ViewDataDictionary vd, object clientData)' y la fila de retorno a 'var htmlHelper = new HtmlHelper (mockViewContext.Object, mockViewDataContainer .Objeto); htmlHelper.ViewBag.Client = clientData; return htmlHelper; ' – LosManos

+0

Es la mejor respuesta hasta el momento, pero no funcionará si tiene un helper html que use htmlHelper. Por ejemplo, si está usando Html.action (...) esto genera una respuesta nula. –

1

Para probar ayudante desechables como BeginForm con acceso a ViewContext.Writer puede utilizar esto:

public static HtmlHelper CreateHtmlHelper(ViewDataDictionary vd, Stream stream = null) 
{ 
    TextWriter textWriter = new StreamWriter(stream ?? new MemoryStream()); 
    Mock<ViewContext> mockViewContext = new Mock<ViewContext>(
     new ControllerContext(
      new Mock<HttpContextBase>().Object, 
      new RouteData(), 
      new Mock<ControllerBase>().Object 
     ), 
     new Mock<IView>().Object, 
     vd, 
     new TempDataDictionary(), 
     textWriter 
    ); 
    mockViewContext.Setup(vc => vc.Writer).Returns(textWriter); 

    Mock<IViewDataContainer> mockDataContainer = new Mock<IViewDataContainer>(); 
    mockDataContainer.Setup(c => c.ViewData).Returns(vd); 

    return new HtmlHelper(mockViewContext.Object, mockDataContainer.Object); 
} 
+0

debe haber algo que falta . Obtuve una 'System.NullReferenceException'. "Referencia a objeto no establecida como instancia de un objeto". ¿Alguna idea? – Blaise

+0

Probablemente necesites asegurarte de que 'CallBase' está establecido en verdadero en el objeto simulado para que las propiedades estén configuradas correctamente. No debería tener que hacer 'mockViewContext.Setup (vc => vc.Writer) .Returns (textWriter);' tampoco. –

Cuestiones relacionadas