【问题标题】:Rhino Mocks: Can I use Stub() when one of my parameters is Expression<Func<T1, T2>>?Rhino Mocks:当我的参数之一是 Expression<Func<T1, T2>> 时,我可以使用 Stub() 吗?
【发布时间】:2009-05-13 13:41:33
【问题描述】:

我在一个看起来像这样的接口上有一个方法,我想用 Rhino Mocks 对它进行存根:

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

我的代码如下所示:

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

请注意,该方法中的参数之一是Expression&lt;Func&lt;T1, T2&gt;&gt;,并且此存根未返回指定值。我知道我可以通过使用 WhenCalled() 来做到这一点,但我想知道 Stub() 是否应该使用表达式参数,或者我只是做错了什么。

【问题讨论】:

    标签: rhino-mocks


    【解决方案1】:

    您可以创建一个计算两个表达式之间相等性的方法:

    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));
        }
    }
    

    然后更改您的存根语句以将表达式包装在对表达式匹配器的调用中:

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

    【讨论】:

    • 目前仅适用于表达式中的方法,不适用于属性。您需要将属性匹配添加到表达式匹配器。另外,如果方法有参数,你也需要比较它们。
    • 重要的一点!仍然足够公平 - 对方法很有效。
    【解决方案2】:

    我认为问题与表达式如何测试相等性有关。我刚刚在 Snippet Compiler 中做了一个快速测试,但我的表达式从未被评估为相同:

        Expression<Func<int, string>> p = i => i.ToString();
        Expression<Func<int, string>> s = i => i.ToString();
        var b = p.Equals(s) || p == s;
    

    (此测试中 b 为假)

    可能为了让您的测试按原样工作,您必须忽略第二个参数的实际值(这可能可接受也可能不可接受;如果不可接受,我认为您将不得不走 WhenCalled 路线) .

    【讨论】:

    • 您的测试证明了为什么这不起作用,但如果两个表达式仅包含一个属性并且它们引用相同的属性,您似乎应该能够确定它们是否相等。看起来 Rhino Mocks 不会那样做,但如果那样做就好了!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多