2009-05-13 3 views
6

Ich habe eine Methode für eine Schnittstelle, die so aussieht, und ich will es mit Rhino Mocks Stub:Rhino Mocks: Kann ich Stub() verwenden, wenn einer meiner Parameter Ausdruck <Func<T1, T2>> ist?

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

Mein Code, der das Anstoßen wie folgt aussieht tut:

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

Beachten Sie, dass ein der Parameter in dieser Methode ist ein Expression<Func<T1, T2>>, und dieser Stub gibt den angegebenen Wert nicht zurück. Ich weiß, dass ich das mit WhenCalled() tun kann, aber ich habe mich gefragt, ob Stub() mit Ausdrucksparametern arbeiten sollte oder ob ich gerade etwas falsch mache.

Antwort

3

Sie eine Methode erstellen, die die Gleichheit zwischen zwei Ausdrücke auswertet:

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

dann Ihre Stub-Anweisung ändern Sie den Ausdruck in einem Aufruf der Ausdruck Matcher zu wickeln:

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

Dies funktioniert derzeit nur für Methoden im Ausdruck, nicht für Eigenschaften. Sie müssten dem Expression Matcher eine passende Eigenschaft hinzufügen. Wenn die Methode Argumente enthält, müssen Sie diese ebenfalls vergleichen. – Tim

+0

Wichtiger Punkt! Immer noch fair - funktionierte gut für Methoden. – Jan

2

Ich denke, das Problem hängt damit zusammen, wie Ausdrücke Gleichheit testen. Ich habe gerade einen schnellen Test in Snippet Compiler und meine Ausdrücke nie als gleich bewertet:

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

(b falsch war für diesen Test)

Wahrscheinlich, um für den Test als zu arbeiten, Sie‘ d muss den tatsächlichen Wert des zweiten Parameters ignorieren (der möglicherweise akzeptabel ist oder nicht; wenn es inakzeptabel ist, denke ich, dass Sie die WhenCalled Route gehen müssen).

+0

Ihr Test beweist Warum das nicht funktioniert, aber es scheint, dass Sie in der Lage sein sollten festzustellen, ob zwei Ausdrücke gleich sind, wenn sie jeweils nur eine Eigenschaft enthalten und auf dieselbe Eigenschaft verweisen. Sieht nicht so aus, als würde Rhino Mocks das tun, aber es wäre schön, wenn es so wäre! –

Verwandte Themen