2010-03-22 8 views
51

Ich denke, ich bin ein wenig verwirrt über die Syntax der Moq Callback-Methoden. Wenn ich versuche, so etwas zu tun:Einstellungen Variablenwerte in einem Moq Callback() Anruf

IFilter filter = new Filter(); 
List<IFoo> objects = new List<IFoo> { new Foo(), new Foo() }; 

IQueryable myFilteredFoos = null; 
mockObject.Setup(m => m.GetByFilter(It.IsAny<IFilter>())) 
    .Callback((IFilter filter) => myFilteredFoos = filter.FilterCollection(objects)) 
    .Returns(myFilteredFoos.Cast<IFooBar>()); 

Diese eine Ausnahme auslöst, weil myFilteredFoos während der Cast<IFooBar>() Aufruf null ist. Funktioniert das nicht so, wie ich es erwarte? Ich würde denken, FilterCollection würde aufgerufen werden und dann myFilteredFoos wäre nicht null und für die Besetzung zulassen.

FilterCollection ist nicht in der Lage, eine Null zurückzugeben, die mich zu dem Schluss zieht, dass sie nicht aufgerufen wird. Auch, wenn ich erklären myFilteredFoos wie folgt aus:

Queryable myFilteredFoos; 

Der Rückruf beklagt, dass myFilteredFoos verwendet werden kann, bevor es initialisiert wird.

Antwort

75

Dies ist, weil der Code in der Returns Methode sofort ausgewertet wird; das heißt, wenn die Setup-Methode aufgerufen wird.

Der Rückruf wird jedoch erst aufgerufen, wenn die Methode aufgerufen wird.

Zum Glück, die Returns Methode ist überlastet, so dass Sie seine Ausführung verschieben können auch:

mockObject.Setup(m => m.GetByFilter(It.IsAny<IFilter>())) 
    .Callback((IFilter filter) => 
     myFilteredFoos = filter.FilterCollection(objects)) 
    .Returns(() => myFilteredFoos.Cast<IFooBar>()); 

Allerdings brauchen Sie nicht den Wert in einem Rückruf zu speichern, da Sie nur die Parameter bekommen Wert direkt in der Returns Methode:

mockObject.Setup(m => m.GetByFilter(It.IsAny<IFilter>())) 
    .Returns((IFilter filter) => 
     filter.FilterCollection(objects).Cast<IFooBar>()); 
+0

Danke für die Antwort und die Code-Reduzierung! –

13

Sie können nur die Parameter im Rückgabewert nehmen ...

mockObject 
    .Setup(m => m.GetByFilter(It.IsAny<IFilter>())) 
    .Returns((IFilter filter) => 
    { 
     myFilteredFoos = filter.FilterCollection(objects); 

     return myFilteredFoos.Cast<IFooBar>(); 
    }); 
Verwandte Themen