我想通过将服务名称提供为字符串来模拟服务方法:
public interface IService
{
SomeType SomeMethod(int a, int b);
}
...
var service = new Mock<IService>();
string methodName = nameof(IService.SomeMethod);
service.Setup(s => s."methodName"(It.IsAny<int>(), It.IsAny<int>())
.Callback<int, int>(...faking is not related);
我知道我必须以某种方式使用Expression,但是我无法想象如何基于IService和It.IsAny参数来创建此表达式。
答案 0 :(得分:2)
您可以构造一个表达式,例如如下:
private static Expression<Action<T>> ConstructMethodCallExpressionWithItIsAnyOnAllArguments<T>(string mehodName)
{
var methodInfo = typeof(T).GetMethod(mehodName);
var argumentExpression = Expression.Parameter(typeof(T));
var methodExpression = Expression.Call(
argumentExpression,
methodInfo,
methodInfo.GetParameters().Select(pi => Expression.Call(
typeof(It), "IsAny", new Type[] { pi.ParameterType }, new Expression[0])));
var result = Expression.Lambda<Action<T>>(
methodExpression,
argumentExpression);
return result; //E.g.: Expression<Action<IService>>(s => s.SomeMethod(It.IsAny<int>(), It.IsAny<int>())
}
用法:
var service = new Mock<IService>();
string methodName = nameof(IService.SomeMethod);
service.Setup(ConstructMethodCallExpressionWithItIsAnyOnAllArguments<IService>(methodName))
.Callback<int, int>((x, y) => { ... });
如果需要Func
表达式:
private static Expression<Func<T, TResult>> ConstructMethodCallExpressionFunc<T, TResult>(string mehodName)
{
var methodInfo = typeof(T).GetMethod(mehodName);
var argumentExpression = Expression.Parameter(typeof(T));
var methodExpression = Expression.Call(
argumentExpression,
methodInfo,
methodInfo.GetParameters().Select(pi => Expression.Call(
typeof(It), "IsAny", new Type[] { pi.ParameterType }, new Expression[0])));
var result = Expression.Lambda<Func<T, TResult>>(
methodExpression,
argumentExpression);
return result; //E.g.: Expression<Func<IService, string>>(s => s.SomeMethod(It.IsAny<int>(), It.IsAny<int>())
}
使用方式:
var service = new Mock<IService>();
string methodName = nameof(IService.SomeMethod);
service.Setup(ConstructMethodCallExpressionFunc<IService, string>(methodName))
.Returns<int, int>((x, y) => (x.ToString() + y.ToString()));