Lambda表达式参数

时间:2014-05-08 17:14:55

标签: c# lambda task-parallel-library moq func

我试图为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;这里的变量变为空。

1 个答案:

答案 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参数的类型后面有TResultvalueFunc类型参数。