Moq使用表达式树进行配置,因此您可以通过构建各种
Expression<Action<ITest>>
实例。仅举一个例子,说明如何在您的特定情况下实现:
public interface ITest
{
void Method1(bool readMode, List<int> list);
void Method2(bool readMode, List<int> list);
void Method3(bool readMode, List<string> list);
}
[Test]
public void Method1Test()
{
Mock<ITest> test = new Mock<ITest>();
TestAnyMethod<ITest, int>(test, "Method1");
TestAnyMethod<ITest, int>(test, "Method2");
TestAnyMethod<ITest, string>(test, "Method3");
test.VerifyAll();
}
private void TestAnyMethod<T, TItem>(Mock<ITest> test, string methodName)
{
var type = typeof(T);
var methodInfo = type.GetMethod(methodName);
test.Setup(Verifiable<TItem>(type, methodInfo)).Verifiable();
methodInfo.Invoke(test.Object, new object[] {true, new List<TItem>{ default(TItem) } });
methodInfo.Invoke(test.Object, new object[] {true, new List<TItem> { default(TItem), default(TItem) } });
test.Verify(VerifyReadMode<TItem>(type, methodInfo, true), Times.AtLeastOnce());
test.Verify(VerifyReadMode<TItem>(type, methodInfo, false), Times.Never());
test.Verify(VerifyListCount<TItem>(type, methodInfo, 0), Times.Never());
test.Verify(VerifyListCount<TItem>(type, methodInfo, 2), Times.Once());
}
private Expression<Action<ITest>> Verifiable<T>(Type mockingType, MethodInfo method)
{
var readModeArg = Expression.Call(typeof(It), "IsAny", new []{ typeof(bool) });
var listArg = Expression.Call(typeof(It), "IsAny", new[] { typeof(List<T>) });
return Verify(mockingType, method, readModeArg, listArg);
}
private Expression<Action<ITest>> VerifyReadMode<T>(Type mockingType, MethodInfo method, bool readMode)
{
var readModeArg = Expression.Constant(readMode);
var listArg = Expression.Call(typeof(It), "IsAny", new[] { typeof(List<T>) });
return Verify(mockingType, method, readModeArg, listArg);
}
private Expression<Action<ITest>> VerifyListCount<T>(Type mockingType, MethodInfo method, int count)
{
var readModeArg = Expression.Call(typeof(It), "IsAny", new[] { typeof(bool) });
var listPrm = Expression.Parameter(typeof(List<T>), "y");
var prop = Expression.Property(listPrm, typeof(List<T>), "Count");
var equal = Expression.Equal(prop, Expression.Constant(count));
var lambda = Expression.Lambda<Func<List<T>, bool>>(equal, "y", new [] { listPrm });
var listArg = Expression.Call(typeof(It), "Is", new[] { typeof(List<T>) }, lambda);
return Verify(mockingType, method, readModeArg, listArg);
}
private Expression<Action<ITest>> Verify(Type mockingType, MethodInfo method, Expression readModeArg, Expression listArg)
{
var prm = Expression.Parameter(mockingType, "x");
var methodCall = Expression.Call(prm, method, readModeArg, listArg);
Expression<Action<ITest>> expr = Expression.Lambda<Action<ITest>>(methodCall, "x", new[] { prm });
return expr;
}
希望有帮助。