C# 使用表达式模拟泛型方法中的泛型返回类型

C# 使用表达式模拟泛型方法中的泛型返回类型,c#,generics,moq,C#,Generics,Moq,我有以下带有泛型方法的接口 公共接口IRepository{ 任务GetByIdAsync( int id, 表情表情, TResult defaultValue=默认值); } 在代码的某些部分,表达式返回元组和匿名类型 示例 var\u repository=ServiceProvider.GetRequiredService(); var data=await_repository.GetByIdAsync(id,pr=>Tuple.Create(pr,pr.selfreObject))

我有以下带有泛型方法的接口

公共接口IRepository{
任务GetByIdAsync(
int id,
表情表情,
TResult defaultValue=默认值);
}
在代码的某些部分,表达式返回元组和匿名类型

示例

var\u repository=ServiceProvider.GetRequiredService();
var data=await_repository.GetByIdAsync(id,pr=>Tuple.Create(pr,pr.selfreObject));
var data=await_repository.GetByIdAsync(id,pr=>new{pr.selfreObjectId});
是否可以模拟该方法,使其返回具有所述类型的指定值

示例

var\u repositoryMock=new Mock();
var anonymousReturnValue=new{selfreObjectId=1};
_重置模拟
.Setup(pr=>pr.GetByIdAsync(
entityId,
pr=>new{pr.selfreObjectId},
(违约)
.ReturnsAsync(匿名返回值)
.可验证();
var tupleReturnValue=Tuple.Create(新实体(),新实体());
_重置模拟
.Setup(pr=>pr.GetByIdAsync(
entityId,
pr=>Tuple.Create(pr,pr.selfreObject),
(违约)
.ReturnsAsync(tupleReturnValue)
.可验证();

提前谢谢。

简言之:据我所知,你不能这样做

有两种非常有用的助手类型:
It.IsAnyType
It.IsSubType

在设置阶段,您可以使用它们来判断函数是否接受任何内容:

\u repositoryMock
.Setup(repo=>repo.GetByIdAsync(
It.IsAny(),
It.IsAny(),
It.IsAny())
.可验证();
或者它只接受匿名类型或元组:

\u repositoryMock
.Setup(repo=>repo.GetByIdAsync(
It.IsAny(),
It.Is((o,type)=>type.IsAnonymousType()),
It.Is((o,type)=>type.IsAnonymousType())
.可验证();
_重置模拟
.Setup(repo=>repo.GetByIdAsync(
It.IsAny(),
It.Is((o,type)=>type.IsTuple()),
It.Is((o,type)=>type.IsTuple())
.可验证();
助手方法:

公共静态类类型扩展
{
公共静态bool IsAnonymousType(此类型)
{
var hascollergeneratedattribute=type.GetCustomAttributes(typeof(CompilerGeneratedAttribute),false).Any();
var nameContainsAnonymousType=type.FullName!=null&&type.FullName.Contains(“匿名类型”);
返回hasCompilerGeneratedAttribute&&NameContainesAnonymousType;
}
公共静态布尔IsTuple(此类型)
{
如果(!type.IsGenericType)返回false;
var openType=type.GetGenericTypeDefinition();
返回openType==typeof(Tuple)| | openType==typeof(Tuple)
||openType==typeof(ValueTuple)| | openType==typeof(ValueTuple);
}
}
当您需要指定
Return/ReturnAsync
部分时,就会出现问题

\u repositoryMock
.Setup(repo=>repo.GetByIdAsync(
It.IsAny(),
It.Is((o,type)=>type.IsTuple()),
It.Is((o,type)=>type.IsTuple())
.Returns(valueFunction:()=>Task.FromResult(tupleReturnValue));
它无法编译,因为它无法将
Tuple
转换为
Mock.It.IsAnyType

严重性代码说明项目文件行抑制状态 错误CS0029无法隐式转换类型“System.Threading.Tasks.Task”