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

如何为带Func参数的泛型GetOrCreate方法配置Moq?

问题描述

我定义了如下泛型接口:

public interface IMemoryCacheWithPolicy
{
    TItem GetOrCreate<TItem>(object key, Func<TItem> createItem, CacheItemPriority priorityLevel);
}

并通过以下方式调用该方法:

var materials = _cacheProvider.GetOrCreate("ActiveMaterials",
    () => _materialService.GetMaterials(false), CacheItemPriority.Normal);

在对调用该方法的类进行单元测试时,我需要为IMemoryCacheWithPolicy配置Moq,但尝试了多种方案均未成功,以下是我尝试过的配置:

_mockCacheProvider.Setup(
    x =>
        x.GetOrCreate("ActiveMaterials", It.IsAny<Func<IEnumerable<MaterialModel>>>(),
            It.IsAny<CacheItemPriority>())).Returns(_allMaterials);

_mockCacheProvider.Setup(
    foo =>
        foo.GetOrCreate<IEnumerable<MaterialModel>>("ActiveMaterials",
            (Func<It.IsAnyType>)It.IsAny<object>(),
            It.IsAny<CacheItemPriority>())).Returns(_allMaterials);

请问如何正确配置Moq?


正确配置方案

方式一:严格匹配优先级参数

明确指定泛型方法的类型参数,同时准确匹配调用时的参数:

_mockCacheProvider
    .Setup(x => x.GetOrCreate<IEnumerable<MaterialModel>>(
        "ActiveMaterials", 
        It.IsAny<Func<IEnumerable<MaterialModel>>>(), 
        CacheItemPriority.Normal))
    .Returns(_allMaterials);

方式二:宽松匹配优先级参数

如果不需要严格校验优先级的值,可以用通配符匹配:

_mockCacheProvider
    .Setup(x => x.GetOrCreate<IEnumerable<MaterialModel>>(
        "ActiveMaterials", 
        It.IsAny<Func<IEnumerable<MaterialModel>>>(), 
        It.IsAny<CacheItemPriority>()))
    .Returns(_allMaterials);

失败原因说明
  • 第一种尝试未指定泛型方法的<IEnumerable<MaterialModel>>类型参数,Moq无法识别要匹配的泛型方法重载。
  • 第二种尝试中的(Func<It.IsAnyType>)It.IsAny<object>()属于错误的类型转换,Func<TItem>是强类型委托,不能用object类型来模糊匹配,直接使用对应类型的It.IsAny<Func<...>>即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 03:27:06