Kor*_*bin 17 asp.net-mvc unit-testing mocking
我如何模拟ControllerContext对象上的缓存对象以进行单元测试?我已经尝试创建一个类似下面的包装类(因为缓存对象是一个密封的类),没有运气.
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;
Run Code Online (Sandbox Code Playgroud)
tva*_*son 21
编辑:我发现了一种更简单的方法,至少在使用空缓存进行测试时.使用HttpRunTime.Cache作为HttpContext的Cache属性的期望返回值.对于更高级的场景,使用包装器和模拟可能仍然是处理它的更好方法 - 例如,如果您需要从缓存中测试异常.
var httpContext = MockRepository.GenerateMock<HttpContextBase>();
httpContext.Expect( h => h.Cache ).Return( HttpRunTime.Cache ).Repeat.Any()
Run Code Online (Sandbox Code Playgroud)
原文:
包装类是要走的路,但我认为你是在错误的地方应用它.我会给我的控制器一个CacheWrapper属性,然后创建一个构造函数,允许我传入一个可以设置此属性的CacheWrapper实例.默认情况下,控制器使用HttpContext.Current.Cache创建CacheWrapper.在您的测试代码中,构造一个模拟CacheWrapper以传递给控制器的构造函数.这样你根本不需要创建一个模拟Cache对象 - 这很难,因为它是一个密封的类.
或者,您可以实例化Cache类的实例并将其返回,因为它有一个公共构造函数.使用mock有一个优点,你可以通过期望来验证Cache是否被使用,所以我可能会使用包装器.
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();
}
Run Code Online (Sandbox Code Playgroud)
Cle*_*ud8 11
我建议使用微软新的MemoryCache.Default方法.您将需要使用.NET Framework 4.0或更高版本,并包含对System.Runtime.Caching的引用.
请参阅此处的文章 - > http://msdn.microsoft.com/en-us/library/dd997357(v=vs.100).aspx
MemoryCache.Default适用于Web和非Web应用程序.因此,您的想法是更新您的webapp以删除对HttpContext.Current.Cache的引用,并将其替换为对MemoryCache.Default的引用.稍后,当您决定对这些相同的方法进行单元测试时,缓存对象仍然可用,并且不会为空.(因为它不依赖于HttpContext.)
这样您甚至不一定需要模拟缓存组件.
HttpContext.Current = new HttpContext(new HttpRequest(null, "http://tempuri.org", null), new HttpResponse(null));
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7538 次 |
| 最近记录: |