我正在编写一些单元测试,我想知道模拟Cache
是否有利,如果是,那该怎么办?
目前在我的测试中,我正在嘲笑HttpContextBase
并将其包装在自定义HttpContextFactory
中:
var mockedHttpContextBase = new Mock<HttpContextBase>();
IHttpContextFactory httpContextFactory = new HttpContextFactory
{
Current = mockedHttpContextBase.Object
};
当我的代码消耗IHttpContextFactory
时,我在使用它之前检查缓存是否为空。
var cache = _httpContextFactory.Current.Cache;
Func<SomeReturnType> doSomeWork = () => _foo.someMethodIExecute(param1,param2);
return cache != null ? cache.GetOrStore("doSomeWorkCacheKey",doSomeWork, 900)
: doSomeWork.Invoke();
每次使用它时都检查缓存是否为空是否正确,或者您是否也在测试中模拟缓存,以便在运行单元测试时它不为空?
答案 0 :(得分:13)
经过一些搜索后,我在编写单元测试时似乎可以使用HttpRuntime.Cache
代替System.Web.Caching.Cache
。
这样:
var mockedHttpContextBase = new Mock<HttpContextBase>();
mockedHttpContextBase.Setup(m => m.Cache).Returns(HttpRuntime.Cache);
缓存永远不应该是null
(如果是的话,它将是一个适当的例外),所以我可以从我的代码中删除空引用检查。
答案 1 :(得分:4)
如果您的代码假定缓存可以是null
并在访问之前执行检查(就像现在一样),则需要为每个缓存访问进行两次单元测试:
GetOrStore
调用)如果这是常见模式(空检查),而不是每次需要缓存依赖项时都要进行两次测试,我建议将其包装到Null Object Pattern并测试一次,之后只需使用NOP作为依赖项即可被嘲笑。
编辑:缓存“模拟”示例
var cache = new Cache();
// Add takes more parameters; fill whatever is necessary to make it work
cache.Add("doSomeWorkCacheKey", doSomeWork, ...);
var mockedHttpContextBase = new Mock<HttpContextBase>();
// tell your mock to return pre-configured cache
mockedHttpContextBase.Setup(m => m.Cache).Returns(cache);
IHttpContextFactory httpContextFactory = new HttpContextFactory
{
Current = mockedHttpContextBase.Object
};