模拟System.Web.Caching.Cache - 模拟或检查null?

时间:2012-04-30 10:59:31

标签: c# unit-testing caching design-patterns moq

我正在编写一些单元测试,我想知道模拟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();

每次使用它时都检查缓存是否为空是否正确,或者您是否也在测试中模拟缓存,以便在运行单元测试时它不为空?

2 个答案:

答案 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调用)
  • cache为null,您只需断言委托调用

如果这是常见模式(空检查),而不是每次需要缓存依赖项时都要进行两次测试,我建议将其包装到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 
};