You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

编写单元测试时如何为HandleMemoryCache传入IMemoryCache依赖参数

构造参数传入方案

你标记的#####位置有两种成熟的传参方式,适配不同测试场景:

方案1:传入真实IMemoryCache实现(优先推荐)

IMemoryCache本身是微软提供的无外部依赖的轻量实现,直接实例化传入即可,能100%还原生产环境的缓存行为,不会出现模拟逻辑和真实运行逻辑不一致的问题,最适合测试你这种缓存包装类。

  • 先给测试项目安装Microsoft.Extensions.Caching.Memory NuGet包
  • 直接初始化真实MemoryCache实例传入,完整测试代码如下:
// arrange
string key = "TestKey";
string value = "TestValue";
// 初始化内存缓存,传入必填的配置项即可,空配置满足测试需求
using IMemoryCache realMemoryCache = new MemoryCache(new MemoryCacheOptions());
IHandleMemoryCache inMemoryCache = new HandleMemoryCache(realMemoryCache);

// act
inMemoryCache.WriteEntry(key, value);

// assert
Assert.That(value, Is.EqualTo(inMemoryCache.ReadEntry(key)));

注意:MemoryCache实现了IDisposable接口,测试中用using包裹会自动完成资源释放。

方案2:用Mock框架模拟IMemoryCache实例(按需选择)

如果你只需要验证类和缓存的交互逻辑、不需要验证真实缓存读写效果,可以用Moq这类Mock框架模拟IMemoryCache实例,注意需要把HandleMemoryCache内部调用的缓存方法全部配置正确,否则测试结果会失真。

  • 给测试项目安装Moq NuGet包
  • 配置Mock对象的读写逻辑后传入,示例代码如下:
// arrange
string key = "TestKey";
string value = "TestValue";
object storedCacheValue = null;
var mockMemoryCache = new Mock<IMemoryCache>();
// 配置缓存读逻辑
mockMemoryCache
    .Setup(cache => cache.TryGetValue(It.IsAny<object>(), out storedCacheValue))
    .Returns((object cacheKey, out object outValue) =>
    {
        outValue = storedCacheValue;
        return storedCacheValue != null;
    });
// 配置缓存写逻辑
mockMemoryCache
    .Setup(cache => cache.CreateEntry(It.IsAny<object>()))
    .Returns((object cacheKey) =>
    {
        var mockEntry = Mock.Of<ICacheEntry>();
        Mock.Get(mockEntry)
            .SetupSet(entry => entry.Value = It.IsAny<object>())
            .Callback<object>(inputVal => storedCacheValue = inputVal);
        return mockEntry;
    });

IHandleMemoryCache inMemoryCache = new HandleMemoryCache(mockMemoryCache.Object);

// act
inMemoryCache.WriteEntry(key, value);

// assert
Assert.That(value, Is.EqualTo(inMemoryCache.ReadEntry(key)));

不推荐优先用Mock方案:你的HandleMemoryCache是对IMemoryCache的薄包装,用Mock需要自己手动实现一遍缓存读写逻辑,很容易和真实缓存行为脱节,测不出实际问题。


额外说明:你参考的问题《单元测试中的依赖注入:如何向我注入的类中传入依赖?》核心结论就是:单元测试不需要复用生产环境的DI容器注册逻辑,直接手动构造依赖传入待测试类即可,不需要在测试项目里单独搭建ServiceCollection做依赖注入,反而会增加测试复杂度。

内容的提问来源于stack exchange,提问作者Glyn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 20:27:28