24. August 2009 21:41
I ran into an interesting problem today while unit testing some code that depended upon System.Web.Cache where the Cache object itself was instantiated, but the internal dictionary was not. What happens is you end up getting null reference exceptions when you try add, remove, etc. anything from the Cache while unit testing. For example:
Kinda dififcult to spot what the issue is since it looks like the error is caused by the "PageTemplateKey" not matching on a cached item, but that's not the behavior of System.Web.Caching.Cache. When an item does not exist, null is returned...so what else could be causing this? The "'ContentFactory.Cache.Count' threw and exception" is the dead give away. The internal cache object was not being created in a non server environment.
For my unit tests I am using the Moq framework and mocking the major players of the ASP.NET HTTP stack. Notice that when I perform the setup on the mockContext object below I am setting the return value to be a new Cache(), this is where I am running into the issues described above.
So what to do now? There are at the least to ways to work around this issue: 1) create a mock cache wrapper or 2) use System.Web.HttpRuntime.Cache as a replacement. Opting for simplicity, I switched out the code on my MakeMockContext method to use System.Web.HttpRuntime.Cache and viola, problem solved:
This worked like a charm:
The reason why this works is that System.Web.Cache uses CacheInternal, which you guessed it, is set by an internal setter, called SetInternalCache. HttpRuntime directly makes the call to create CacheInternal when you access the HttpRuntime.Cache property.