我试图为Moq创建一个扩展方法,我可以在其中发送一个表达式,用于异步返回函数。但是这个问题并不是特定的Moq。这就是我到目前为止所拥有的:
public static IReturnsResult<TMock> ReturnsAsync<TMock, TResult, T>(this IReturns<TMock, Task<TResult>> setup, Func<T, TResult> valueFunc) where TMock : class
{
return setup.Returns(Task.FromResult(valueFunc.Invoke(default(T))));
}
这就是我希望使用它的方式。
repo.Setup(x => x.FindAsync(It.IsAny<Expression<Func<T, bool>>>())).ReturnsAsync((Expression<Func<T, bool>> e) => context.GetSet<T>().FirstOrDefault(e));
现在我真的不知道所有这些是如何工作的,我能弄清楚的是如何将表达式传递给ReturnsAsync函数,以便我可以将它作为参数使用我在那里作为占位符的默认值(T)。
正如预期的那样&#34; e&#34;这里的变量变为空。
答案 0 :(得分:2)
此方法可以执行您想要的操作:
public static IReturnsResult<TMock> ReturnsAsync<TMock, TResult, T>(
this IReturns<TMock, Task<TResult>> setup,
Func<Expression<Func<TResult, T>>, TResult> valueFunc)
where TMock : class
{
return setup.Returns<Expression<Func<TResult, T>>>(
e => Task.FromResult(valueFunc(e)));
}
然后像这样使用它:
repo.Setup(x => x.FindAsync(It.IsAny<Expression<Func<T, bool>>>()))
.ReturnsAsync<IRepository, int, bool>(e => context.GetSet<T>().FirstOrDefault(e));
本质上,此版本的ReturnsAsync
采用一个期望谓词函数(e
)并返回T
的函数。这允许您根据测试数据集(context.GetSet<T>.FirstOrDefault
)执行谓词。另外,我使用了接受类型参数的Returns
重载;这用于将Setup
调用中的参数转发到指定为Returns
参数的函数。
您的版本的签名仅指定了谓词,因此您无法针对测试数据执行它。您还在T
参数的类型后面有TResult
和valueFunc
类型参数。