2010-03-22 4 views
51

Je pense que je peux être un peu confus sur la syntaxe des méthodes Moq Callback. Lorsque je tente de faire quelque chose comme ceci:Valeurs de variables de paramètres dans un appel Moq Callback()

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

Cela jette une exception, car myFilteredFoos est nul lors de l'appel Cast<IFooBar>(). Est-ce que ça ne marche pas comme je m'y attends? Je pense que FilterCollection serait appelé, puis myFilteredFoos serait non nul et permettre la distribution.

FilterCollection n'est pas capable de retourner une valeur nulle qui m'attire à la conclusion qu'elle n'est pas appelée. Aussi, quand je déclare myFilteredFoos comme ceci:

Queryable myFilteredFoos; 

L'appel de retour se plaint que myFilteredFoos peut être utilisé avant qu'il ne soit initialisé.

Répondre

75

En effet, le code dans la méthode Returns est évaluée immédiatement; c'est-à-dire lorsque la méthode Setup est appelée.

Cependant, le rappel n'est pas appelé jusqu'à ce que la méthode GetByFilter soit invoquée.

Heureusement, la méthode Returns est surchargée de sorte que vous pouvez reporter son exécution ainsi:

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

Cependant, vous n'avez pas besoin d'enregistrer la valeur dans un rappel, parce que vous pouvez juste obtenir le paramètre valeur directement dans la Returns méthode:

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

Merci pour la réponse et la réduction de code! –

13

Vous pouvez simplement prendre le paramètre de la valeur de retour ...

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

     return myFilteredFoos.Cast<IFooBar>(); 
    }); 
Questions connexes