我有一个Rhino-mocked对象,我有一个MethodInfo表示被模拟的接口上的方法。我想告诉是否已经在模拟对象上调用了MethodInfo表示的方法。
如果我在编译时知道该方法,我会使用Rhino AssertWasCalled()方法。
如果我有一两天的备用,我可能会用表达树法术来生成代码,但这不仅仅是这个问题的当前价值。
我想知道我是否错过了一个更简单的方法。任何想法都赞赏。
答案 0 :(得分:1)
你认为在这里使用表达式树会使事情变得太复杂,但我不同意:
// What you have:
var methodInfo = typeof(ICloneable).GetMethod("Clone");
var parameter = Expression.Parameter(typeof(ICloneable), "p");
var body = Expression.Call(parameter, methodInfo);
// Rhino can accept this as an expectation.
var lambda = Expression.Lambda<Action<ICloneable>>(body, parameter).Compile();
然后使用它:
var clone = new MockRepository().Stub<ICloneable>();
clone.Replay();
clone.Clone();
clone.AssertWasCalled(lambda);
答案 1 :(得分:0)
根据上面Ani的有用评论,我最终得到了以下内容。
这是测试代码,所以我对GetParameters()[0]
恐怖感到乐观!
protected static object InvokeOldOperation<TCurrentInterface>(MethodInfo oldOperationMethod, object implToTest, TCurrentInterface mockCurrentImpl)
{
MethodInfo currentInterfaceMethod = typeof(TCurrentInterface).GetMethod(oldOperationMethod.Name);
Type oldRequestType = oldOperationMethod.GetParameters()[0].ParameterType;
var request = Activator.CreateInstance(oldRequestType);
Type currentRequestType = currentInterfaceMethod.GetParameters()[0].ParameterType;
ParameterExpression instanceParameter = Expression.Parameter(typeof(TCurrentInterface), "i");
var requestParameter = Expression.Constant(null, currentRequestType);
MethodCallExpression body = Expression.Call(instanceParameter, currentInterfaceMethod, new Expression[] { requestParameter});
var lambda = Expression.Lambda<Func<TCurrentInterface, object>>(body, instanceParameter).Compile();
var response = oldOperationMethod.Invoke(implToTest, new[] {request});
mockCurrentImpl.AssertWasCalled(lambda, opt => opt.Constraints(Is.TypeOf(currentRequestType)).Repeat.Once());
return response;
}