1

我有一个 Rhino 模拟对象,并且我有一个 MethodInfo 表示正在模拟的接口上的方法。我想知道 MethodInfo 所代表的方法是否已经在 mock 对象上被调用。

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

如果我有一两天的空闲时间,我可能会使用表达式树的魔法来生成代码,但这比这个问题目前的价值要高。

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

4

2 回答 2

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);
于 2012-08-21T14:11:44.343 回答
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;
    }
于 2012-08-21T15:08:21.753 回答