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

Jam*_*xon 8 c# caching unit-testing design-patterns moq

我正在写一些单元测试,我想知道模拟它是否有利Cache,如果是,如何?

目前在我的测试中,我正在嘲笑HttpContextBase并将其包装在自定义中HttpContextFactory:

var mockedHttpContextBase = new Mock<HttpContextBase>();

IHttpContextFactory httpContextFactory = new HttpContextFactory 
{ 
     Current = mockedHttpContextBase.Object 
};
Run Code Online (Sandbox Code Playgroud)

当我的代码消耗时,我会IHttpContextFactory在执行任何操作之前检查缓存是否为空.

var cache = _httpContextFactory.Current.Cache;

Func<SomeReturnType> doSomeWork = () => _foo.someMethodIExecute(param1,param2);

return cache != null ? cache.GetOrStore("doSomeWorkCacheKey",doSomeWork, 900) 
                     : doSomeWork.Invoke();
Run Code Online (Sandbox Code Playgroud)

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

Jam*_*xon 14

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

这样:

var mockedHttpContextBase = new Mock<HttpContextBase>();
mockedHttpContextBase.Setup(m => m.Cache).Returns(HttpRuntime.Cache);
Run Code Online (Sandbox Code Playgroud)

缓存永远不应该null(如果它是适当的例外),所以我可以从我的代码中删除空引用检查.


k.m*_*k.m 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 
};
Run Code Online (Sandbox Code Playgroud)