I'm trying to create an extension method for Moq where I can send in an expression to be used in an async return function. However this question is not really Moq specific. Here's what I have so far:

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))));
}

This is how I'm hoping to use it.

repo.Setup(x => x.FindAsync(It.IsAny<Expression<Func<T, bool>>>())).ReturnsAsync((Expression<Func<T, bool>> e) => context.GetSet<T>().FirstOrDefault(e));

Now I don't really know how all of this works and the thing I can't figure out is how to I get the expression passed on into the ReturnsAsync function so I can use it as the argument instead of the default(T) that I put there as a placeholder.

As expected the "e" variable here becomes null.

有帮助吗?

解决方案

This method will do what you want:

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)));
}

Then use it like so:

repo.Setup(x => x.FindAsync(It.IsAny<Expression<Func<T, bool>>>()))
    .ReturnsAsync<IRepository, int, bool>(e => context.GetSet<T>().FirstOrDefault(e));

Essentially, this version of ReturnsAsync takes a function that expects a predicate function (which is e) and returns a T. This allows you to then execute the predicate against your test data set (context.GetSet<T>.FirstOrDefault). Also, I used the overload of Returns that accepts a type parameter; this is used to forward the arguments from the Setup call to the function specified as the Returns argument.

Your version's signature only specified the predicate, so you had no way to execute it against your test data. You also had the T and TResult type parameters backwards in the valueFunc parameter's type.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top