viewmodels net mvc filtro busqueda asp asp.net-mvc unit-testing mocking

asp.net-mvc - net - viewmodel c#



¿Cómo te burlas del objeto de almacenamiento en caché en asp.net mvc? (4)

¿Cómo me burlaría del objeto de almacenamiento en caché en el objeto ControllerContext para mis pruebas unitarias? He intentado crear una clase de envoltura como la siguiente (ya que el objeto de caché es una clase sellada) sin suerte.

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;


Puedes intentar usar el Aislador de Typemock , falsifica clases selladas de la caja, por lo que no necesitarás estos envoltorios.


Recomendaría utilizar el nuevo enfoque de Microsoft MemoryCache.Default . Deberá usar .NET Framework 4.0 o posterior e incluir una referencia a System.Runtime.Caching .

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

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

De esta manera, ni siquiera necesariamente tiene que burlarse del componente de caché.


EDITAR : Encontré una forma más fácil de hacer esto, al menos cuando está probando con un caché vacío. Use HttpRunTime.Cache como el valor de retorno para su expectativa en la propiedad Cache del HttpContext. Para escenarios más avanzados, el uso de un envoltorio y burla puede ser una mejor manera de manejarlo, por ejemplo, si necesita probar las excepciones de la caché.

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

Original :

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

Alternativamente, puede simplemente crear una instancia de la clase Cache y devolverla, ya que existe un constructor público para ella. Sin embargo, usar el simulacro tiene la ventaja de que puede verificar que el Caché se está utilizando a través de las expectativas, por lo que es probable que opte por el contenedor.

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(); }


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