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

使用Moq模拟IMemoryCache时无法获取键对应值的问题

问题分析与解决方案

你的测试失败核心源于几个关键错误,以下是具体问题和修正方案:

1. Mock的TryGetValue与存入值完全无关

你在GetMemoryCache方法中给TryGetValue设置的输出参数是初始为null的expectedModel,这个变量和你调用memoryCache.Set存入的expectedValue没有任何关联,导致GetTaskModel调用TryGetValue时始终返回null。

2. 泛型参数类型不匹配

你调用GetTaskModel<Task<It.IsAnyType>>(expectedKey),但实际存入缓存的是string类型的"expectedValue",model as T会因类型不匹配返回null。

3. Mock缓存操作未正确联动

你手动调用memoryCache.Set(expectedKey, expectedValue),但mock的Set方法未被配置为更新TryGetValue的返回值;同时服务实例使用的缓存应与操作的mock实例保持一致,无需额外创建。


修正后的测试代码

[Fact]
public async Task GetTaskModel_GivenTask_ReturnsTask()
{
    // Arrange
    var expectedKey = "expectedKey";
    string expectedValue = "expectedValue";

    // 配置TryGetValue:传入指定key时返回对应值
    _memoryCacheMock
        .Setup(x => x.TryGetValue(expectedKey, out It.Ref<object>.IsAny))
        .Callback((object key, out object value) => value = expectedValue)
        .Returns(true);

    // 可选:验证Set方法是否按预期调用
    _memoryCacheMock
        .Setup(x => x.Set(expectedKey, expectedValue, TimeSpan.FromMinutes(10)))
        .Verifiable();

    var service = new BackgroundTaskTrackerService(_memoryCacheMock.Object);
    service.SetTaskModel(expectedKey, expectedValue);

    // Act
    var result = await service.GetTaskModel<string>(expectedKey);

    // Assert
    Assert.NotNull(result);
    Assert.Equal(expectedValue, result);
    _memoryCacheMock.Verify();
}

关键修正说明

  • 用It.Ref<object>.IsAny配合Callback动态绑定TryGetValue的输出值,确保与存入数据一致。
  • 明确泛型参数为string,与存入类型匹配,避免类型转换失败。
  • 使用服务自身的SetTaskModel方法存入数据,贴合真实业务流程。
  • 将测试改为async Task,直接await异步方法,避免Result可能引发的异步问题。
  • 可选添加验证逻辑,确保Set方法按预期被调用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 23:35:16