2010-03-10 29 views
40

Soy bastante nuevo para usar moq. Estoy en la creación de algunos casos de prueba de unidad a HttpModule y todo funciona bien hasta que llegué a una propiedad de la siguiente manera staticPropiedad estática falsa con moq

this.applicationPath = (HttpRuntime.AppDomainAppVirtualPath.Length > 1) ? HttpRuntime.AppDomainAppVirtualPath : String.Empty; 

No sé cómo crear burla para static clase y propiedad como HttpRuntime.AppDomainAppVirtualPath. El context, request y response se han burlado bien con el código de muestra que obtengo de moq. Apreciaré si alguien puede ayudarme en esto.

Respuesta

57

Moq no puede falsificar miembros estáticos.

Como solución, puede crear una clase contenedora (Patrón de adaptador) que contiene la propiedad estática y falsificar sus miembros.
Por ejemplo:

public class HttpRuntimeWrapper 
{ 
    public virtual string AppDomainAppVirtualPath 
    { 
     get 
     { 
      return HttpRuntime.AppDomainAppVirtualPath; 
     } 
    } 
} 

En el código de producción se puede acceder a esta clase en lugar de HttpRuntime y falsa esta propiedad:

[Test] 
public void AppDomainAppVirtualPathTest() 
{ 
    var mock = new Moq.Mock<HttpRuntimeWrapper>(); 
    mock.Setup(fake => fake.AppDomainAppVirtualPath).Returns("FakedPath"); 

    Assert.AreEqual("FakedPath", mock.Object.AppDomainAppVirtualPath); 
} 

Otra solución es utilizar el marco de aislamiento (como Typemock Isolator) en el que se puede falsificar clases estáticas y miembros.
Por ejemplo:

Isolate.WhenCalled(() => HttpRuntime.AppDomainAppVirtualPath) 
     .WillReturn("FakedPath"); 

Renuncia - Trabajo en Typemock

+5

Al preguntar por Moq, lo que sugiere un producto comerical es un poco fuera. – Finglas

+34

¿Por qué? Es una opción. Envolver estática es mejor, pero conocer tus opciones siempre es algo bueno. –

+2

Está pidiendo una solución sobre cómo hacer esto con Moq. Es por eso. – Finglas

10

No se puede MOq métodos estáticos con Moq.

Esto no es malo en realidad, los métodos y clases estáticos tienen su lugar, pero por lógica dificultan las pruebas unitarias. Naturalmente, te encontrarás con ellos cuando uses otras bibliotecas. Para evitar esto, deberá escribir un adapter (envoltorio) alrededor del código estático y proporcionar una interfaz. Por ejemplo:

// Your static class - hard to mock 
class StaticClass 
{ 
    public static int ReturnOne() 
    { 
     return 1; 
    } 
} 

// Interface that you'll use for a wrapper 
interface IStatic 
{ 
    int ReturnOne(); 
} 

Nota, he omite, la clase concreta que utiliza IStatic para el código de producción. Todo sería una clase que utiliza IStatic y su código de producción haría uso de esta clase, en lugar de StaticClass arriba.

Luego, con Moq:

var staticMock = new Mock<IStatic>(); 
staticMock.Setup(s => s.ReturnOne()).Returns(2); 
+2

@Yasser rompiste el ejemplo del código, estoy revocando tu cambio. – Finglas

3

Como se mencionó en las respuestas anteriores, no se puede utilizar en MoQ métodos estáticos, y si es necesario, su mejor tiro es crear una envoltura alrededor de la estática clase.

Sin embargo, algo que he descubierto recientemente es Moles project. Desde la página de inicio; "Moles permite reemplazar cualquier método .NET con un delegado. Moles admite métodos estáticos o no virtuales". Puede ser útil para su situación actual.

+0

Interesante, lo verificará. – Finglas

+0

No use Moles. En primer lugar, agrega muchos dolores de cabeza y reduce drásticamente los tiempos de construcción. En segundo lugar, ha sido reemplazado porque este comentario fue publicado originalmente por el nuevo marco de burla de Microsoft. En tercer lugar, no es compatible con VS2012 (que usa el marco más nuevo) y es un dolor de cabeza aquí en el trabajo porque tenemos muchas pruebas escritas con Moles aquí que necesitan ser des-Molesified antes de que podamos actualizar. Burlarse de los métodos estáticos es tentador (especialmente para el código heredado), pero IMO si puede, es mejor escribir el código para ser más amigable con las pruebas de unidad. –

+0

Bueno, por supuesto, pero la pregunta se refería a la clase HttpRuntime que la mayoría de nosotros no puede modificar, y en esas circunstancias la necesidad de burlar de alguna manera métodos/propiedades estáticos es inevitable. – haughtonomous

2

La mejor solución que he encontrado hasta ahora es JustMock de Telerik - lamentablemente solo la versión paga permite la burla de la estática.

Si bien la idea de envolver la estática es buena, no siempre se puede hacer esto.Si desea probar algún código que ya usa algunas clases estáticas, no siempre es posible cambiar y usar un contenedor. En este caso, JustMock parece una solución razonable y probablemente la use en algunas soluciones en el futuro cercano.

1

Puede usar Microsoft Fakes para esto. Definitivamente resolverá el problema. Consulte https://msdn.microsoft.com/en-us/library/hh549175.aspx

+1

Aunque este enlace podría responder a la pregunta, siempre es bueno indicar los detalles importantes también en la pregunta (el enlace podría no ser válido). – BDL