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

如何Mock C#中IDistributedCache的GetStringAsync与SetStringAsync扩展方法?

解决IDistributedCache扩展方法无法Mock/验证的问题

你遇到的错误根源很明确:GetStringAsync和SetStringAsync是静态扩展方法,Moq这类Mock框架无法直接对扩展方法做Setup或验证操作。这些扩展方法本质是封装了IDistributedCache接口的原生抽象方法,只需Mock/验证这些底层原生方法即可。

IDistributedCache的原生核心异步方法

扩展方法最终调用的是接口定义的两个抽象方法:

  • Task<byte[]> GetAsync(string key, CancellationToken token = default)
  • Task SetAsync(string key, byte[] value, DistributedCacheEntryOptions options, CancellationToken token = default)

修改你的测试代码

1. 修正GetRecords_with_key测试

把原来验证GetStringAsync的逻辑,改成验证GetAsync,同时匹配字符串转字节数组的默认逻辑:

public async Task GetRecords_with_key()
{
    // Arrange
    var key = "key";
    var cache = _builder.DistributedCache;
    // 若需模拟缓存返回值,可在此Setup GetAsync
    // cache.Setup(x => x.GetAsync(key, default))
    //     .ReturnsAsync(Encoding.UTF8.GetBytes("预期返回内容"));

    var sut = _builder.Build();

    // Act
    await sut.GetRecordAsync<string>(key);

    // Assert
    cache.Verify(x => x.GetAsync(key, It.IsAny<CancellationToken>()), Times.Once);
}

2. 修正Set_Records_with_key测试

原测试的Act步骤调用的是GetRecordAsync,这不会触发缓存写入操作,需改成调用SetRecordAsync;同时把验证SetStringAsync的逻辑替换为验证SetAsync,匹配字符串转字节数组的参数:

public async Task Set_Records_with_key()
{
    // Arrange
    var key = "key";
    var value = "cdc";
    var expectedValueBytes = Encoding.UTF8.GetBytes(value);
    var cache = _builder.DistributedCache;

    var sut = _builder.Build();

    // Act
    await sut.SetRecordAsync(key, value);

    // Assert
    cache.Verify(x => x.SetAsync(
        key, 
        expectedValueBytes, 
        It.IsAny<DistributedCacheEntryOptions>(), 
        It.IsAny<CancellationToken>()), 
        Times.Once);
}

额外提示

  • 若要模拟缓存未命中的场景,只需在SetupGetAsync时返回null即可。
  • 扩展方法默认使用UTF-8编码转换字符串与字节数组,测试时保持编码一致就能匹配参数。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 10:15:14