2009-04-23 8 views
17

¿Cómo me burlaría del objeto de caché en el objeto ControllerContext para las pruebas de mi unidad? Intenté crear una clase contenedora como la siguiente (ya que el objeto de caché es una clase sellada) sin suerte.¿Cómo se burla del objeto de caché en asp.net mvc?

var mockControllerContext = new Mock<ControllerContext>(); 
var mockhttpContext = new Mock<HttpContextBase>();    

mockhttpContext.SetupGet(o => o.Cache).Returns(
     new CacheWrapper(mockControllerContext.Object.HttpContext.Cache)); 

mockControllerContext.SetupGet(
          o => o.HttpContext).Returns(mockhttpContext.Object); 
this.tennisMatchupController.ControllerContext = mockControllerContext.Object; 

Respuesta

20

EDITAR: He encontrado una manera más fácil de hacer esto, por lo menos cuando se está probando con un caché vacía. Use HttpRunTime.Cache como el valor de retorno para su expectativa en la propiedad Cache de HttpContext. Para escenarios más avanzados, usar un contenedor y burlarse puede ser una mejor manera de manejarlo, por ejemplo, si necesita probar excepciones de la memoria caché.

var httpContext = MockRepository.GenerateMock<HttpContextBase>(); 
httpContext.Expect(h => h.Cache).Return(HttpRunTime.Cache).Repeat.Any() 

original:

La clase contenedora es el camino a seguir, pero creo que lo está aplicando en el lugar equivocado. Le daría a mi controlador una propiedad CacheWrapper, luego crearía un constructor que me permitiera pasar una instancia de CacheWrapper a la cual se puede establecer esta propiedad. Por defecto, el controlador crea un CacheWrapper usando HttpContext.Current.Cache. En su código de prueba, construya un falso CacheWrapper para pasar al constructor del controlador. De esta forma, no es necesario crear un objeto de caché falso, lo que es difícil porque es una clase sellada.

Alternativamente, podría instanciar una instancia de la clase Cache y devolverla, ya que hay un constructor público para ella. Usar el simulacro tiene la ventaja de que puedes verificar que el Caché se esté utilizando a través de las expectativas, sin embargo, así que probablemente vaya con el envoltorio.

public class CacheWrapper 
{ 
    private Cache Cache { get; set; } 

    public CacheWrapper() 
    { 
    this.Cache = HttpContext.Current.Cache; 
    } 

    public virtual Object Add(string key, 
          Object value, 
          CacheDependency dependencies, 
          DateTime absoluteExpiration, 
          TimeSpan slidingExpiration, 
          CacheItemPriority priority, 
          CacheItemRemovedCallback onRemoveCallback) 
    { 
    this.Cache.Add(key, 
        value, 
        dependencies, 
        absoluteExpiration, 
        slidingExpiration, 
        priority, 
        onRemoveCallback); 
    } 

    ...wrap other methods... 
} 


public class BaseController : Controller 
{ 
    private CacheWrapper { get; set; } 

    public BaseController() : this(null) { } 

    public BaseController(CacheWrapper cache) 
    { 
     this.CacheWrapper = cache ?? new CacheWrapper(); 
    } 
} 

[TestMethod] 
public void CacheTest() 
{ 
    var wrapper = MockRepository.GenerateMock<CacheWrapper>(); 

    wrapper.Expect(o => o.Add(...)).Return(...); 

    var controller = new BaseController(wrapper); 

    var result = controller.MyAction() as ViewResult; 

    Assert.AreEqual(...); 

    wrapper.VerifyAllExpectations(); 
} 
0

Usted puede tratar de utilizar Typemock Isolator, se sellaron las falsificaciones clases fuera de la caja, por lo que no necesitará estas envolturas.

5
HttpContext.Current = new HttpContext(new HttpRequest(null, "http://tempuri.org", null), new HttpResponse(null)); 
11

Yo recomendaría el uso de nueva MemoryCache.Default enfoque de Microsoft. Tendrá que utilizar .NET Framework 4.0 o posterior e incluir una referencia a System.Runtime.Caching.

Ver artículo aquí ->http://msdn.microsoft.com/en-us/library/dd997357(v=vs.100).aspx

MemoryCache.Default funciona tanto para aplicaciones web y no web. Entonces, la idea es actualizar su aplicación web para eliminar las referencias a HttpContext.Current.Cache y reemplazarlas por referencias a MemoryCache.Default. Más tarde, cuando decida probar la unidad con estos mismos métodos, el objeto de caché seguirá disponible y no será nulo. (Debido a que no depende de un HttpContext.)

De esta forma ni siquiera es necesario que se burle del componente de caché.

+1

La nota excelente realmente ayudó a simplificar todo el proceso – P6345uk

Cuestiones relacionadas