A brief recap of ASP.Net cache:
//in MVC use HttpRuntime.Cache or HttpContext.Cache
//in webforms Application is the original cache without expiration rules
var category = HttpRuntime.Cache["Category"] as CategoryModel;
if (category == null)
{
category = _dataAccess.Find(1);
HttpRuntime.Cache["Category"] = category;
// ...or...
//monitor some files and/or other cache items
var cd = new CacheDependency(new[] { @"C:\triggerFolder\" }, new[] { "OtherCacheItem" });
HttpRuntime.Cache.Insert("Category1", category,
cd, //dependencies or null
DateTime.Now.AddMinutes(5), //absolute expiration (or Cache.NoAbsoluteExporation)
Cache.NoSlidingExpiration //sliding expiration (timespan)
);
}Mocking this in tests (especially for MVC) is a bit ugly (.Net 3.5sp1 has System.Web.Abstractions including HttpContextBase, but caching isn't included)
Now in .Net 4 we can reference
System.Runtime.Caching.dll. And the really nice thing is this will run outside Asp.Net.
//get the static "default" cache. You can have multiple named caches.
ObjectCache cache = MemoryCache.Default;
//you can't store null in the cache
var category = cache["Category"] as CategoryModel;
if (category == null)
{
category = _dataAccess.Find(1);
cache["Category"] = category;
// ...or...
var policy = new CacheItemPolicy();
policy.AbsoluteExpiration = DateTime.Now.AddMinutes(5);
//monitor some files and/or other cache items
policy.ChangeMonitors.Add(
new HostFileChangeMonitor(new List<string> { @"C:\triggerFolder\"})
);
//synchronize with another cache item
policy.ChangeMonitors.Add(
cache.CreateCacheEntryChangeMonitor(new [] { "OtherCacheItem"})
);
cache.Add("Category1", category, policy);
}
For simple caching (no change monitors) you don't even need mocking in your tests - in fact, you can test your caching with a real cache. You can move caching down into your library classes that may be called from web pages, tests, WPF apps and consoles.