AssertWasCalled()等效于编译时未知的方法

时间:2012-08-21 13:40:28

标签: c# reflection rhino-mocks

我有一个Rhino-mocked对象,我有一个MethodInfo表示被模拟的接口上的方法。我想告诉是否已经在模拟对象上调用了MethodInfo表示的方法。

如果我在编译时知道该方法,我会使用Rhino AssertWasCalled()方法。

如果我有一两天的备用,我可能会用表达树法术来生成代码,但这不仅仅是这个问题的当前价值。

我想知道我是否错过了一个更简单的方法。任何想法都赞赏。

2 个答案:

答案 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;
    }