8

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

每次我使用它时检查缓存是否为空是正确的,还是你会在测试中模拟缓存,以便在运行单元测试时它不为空?

4

2 回答 2

14

经过一番搜索,似乎我可以在编写单元测试时使用HttpRuntime.Cache而不是。System.Web.Caching.Cache

这样:

var mockedHttpContextBase = new Mock<HttpContextBase>();
mockedHttpContextBase.Setup(m => m.Cache).Returns(HttpRuntime.Cache);

缓存不应该是null(如果是的话,这将是一个适当的例外),所以我可以从我的代码中删除空引用检查。

于 2012-04-30T13:12:28.163 回答
4

如果您的代码假设缓存可以null并且在访问它之前执行检查(就像现在一样),您需要对每个缓存访问进行两个单元测试:

  • 缓存存在并且项目被存储和检索(检查GetOrStore调用)
  • 缓存为空,您只需断言委托调用

如果这是常见的模式(空检查),我建议不要在每次需要缓存依赖项时进行两次测试,而是将其包装到空对象模式中并对其进行一次测试,然后只需使用 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 
};
于 2012-04-30T11:38:11.877 回答