Mocking System.Web.Caching.Cache - 模拟或检查空值

本文关键字:模拟 检查 空值 Cache System Web Caching Mocking | 更新日期: 2023-09-27 18:32:52

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

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

var mockedHttpContextBase = new Mock<HttpContextBase>();
IHttpContextFactory httpContextFactory = new HttpContextFactory 
{ 
     Current = mockedHttpContextBase.Object 
};

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

var cache = _httpContextFactory.Current.Cache;
Func<SomeReturnType> doSomeWork = () => _foo.someMethodIExecute(param1,param2);
return cache != null ? cache.GetOrStore("doSomeWorkCacheKey",doSomeWork, 900) 
                     : doSomeWork.Invoke();
每次使用缓存时检查缓存

是否为空是否正确,或者您是否也会在测试中模拟缓存,以便在运行单元测试时它不为空?

Mocking System.Web.Caching.Cache - 模拟或检查空值

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

这样:

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

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

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

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

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

另一个答案是使用IMemory缓存的真实实例而不是模拟实例来设置单元测试。