Rhino Mocks: Can I use Stub() when one of the parameters is Expression>

rhino-mocks

I have a method on an interface that looks like this and I want to stub it with Rhino Mocks:

TValue GetPropertyOfExistingObject<TValue>(long id, Expression<Func<T, TValue>> propertyExpression);

My code that does the stubbing looks like this:

var service = MockRepository.GenerateStub<IQuoteService>();
service.Stub(s => s.GetPropertyOfExistingObject(1, q => q.QuoteNumber)).Return(1234);

Notice that one of the parameters in that method is an Expression<Func<T1, T2>>, and this stub is not returning the specified value. I know I can do this by using WhenCalled() but I was wondering if Stub() should work with expression parameters or if I'm just doing something wrong.

Best Solution

You can create a method that evaluates the equality between two expressions:

public class ExpressionMatcher
{
    public static Expression<Action<T>> Matches<T>(Expression<Action<T>> action)
    {
        var methodName = ((MethodCallExpression) action.Body).Method.Name;
        return Arg<Expression<Action<T>>>.Matches(a => ((MethodCallExpression)a.Body).Method.Name.Equals(methodName));
    }
}

Then change your stub statement to wrap the expression in a call to the expression matcher:

service.Stub(s => s.GetPropertyOfExistingObject(Arg<int>.Is.Equal(1), ExpressionMatcher.Matches<Quote>(q => q.QuoteNumber))).Return(1234);
Related Question