如何为带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
相关产品推荐
相关产品推荐

