如何使用Moq模拟泛型方法?
模拟泛型异步方法
MyMethod<T>的问题解决 问题场景
需要模拟的泛型异步方法定义如下:
public async Task<List<T>> MyMethod<T>(string string1, Dictionary<string, string> parameters, string string2) where T : IMyModel, new() {}
无法修改该方法实现,仅需为外部调用做模拟。尝试使用It.IsAny<>匹配参数时,代码报错。
尝试的错误代码
object result = this.myMock .Setup(mock => mock.MyMethod(It.IsAny<string>(), It.IsAny<Dictionary<string, string>>(), It.IsAny<string>())) .ReturnsAsync(new List<MyModel> { myModelInstance });
报错信息
编译器无法从使用中推断出方法
MyMethod<T>的类型参数,请尝试显式指定类型参数。
解决办法
1. 显式指定具体泛型类型
如果调用方明确使用MyModel作为泛型参数,直接在Setup时指定T的类型即可:
var result = this.myMock .Setup(mock => mock.MyMethod<MyModel>(It.IsAny<string>(), It.IsAny<Dictionary<string, string>>(), It.IsAny<string>())) .ReturnsAsync(new List<MyModel> { myModelInstance });
2. 支持任意符合约束的泛型类型
如果需要兼容所有满足IMyModel, new()约束的T类型(Moq 4.13及以上版本支持),可以用It.IsAnyType配合反射创建对应泛型列表:
this.myMock .Setup(mock => mock.MyMethod(It.IsAny<string>(), It.IsAny<Dictionary<string, string>>(), It.IsAny<string>())) .ReturnsAsync((Type t) => Activator.CreateInstance(typeof(List<>).MakeGenericType(t)) as IList);
或者结合参数匹配的完整写法:
this.myMock .Setup(mock => mock.MyMethod(It.IsAny<string>(), It.IsAny<Dictionary<string, string>>(), It.IsAny<string>())) .ReturnsAsync((string _, Dictionary<string, string> __, string ___, Type t) => (IList)Activator.CreateInstance(typeof(List<>).MakeGenericType(t)));
内容的提问来源于stack exchange,提问作者Varda Elentári
相关产品推荐
相关产品推荐

