Lambda表达式参数

本文关键字:参数 表达式 Lambda | 更新日期: 2023-09-27 18:02:20

我试图为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),我把那里作为占位符。

如预期的那样,这里的"e"变量变为null

Lambda表达式参数

这个方法可以满足你的要求:

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参数的函数。

你的版本的签名只指定谓词,所以你没有办法对你的测试数据执行它。您还将TTResult类型参数倒放到了valueFunc参数的类型中。