Je pense que je peux être un peu confus sur la syntaxe des méthodes de rappel Moq. Quand j'essaie de faire quelque chose comme ça:
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 lève une exception car myFilteredFoos
est null pendant l'appel Cast<IFooBar>()
. Cela ne fonctionne-t-il pas comme je m'y attendais? Je pense que FilterCollection
serait appelé, puis myFilteredFoos
serait non nul et autoriserait le cast.
FilterCollection
n'est pas capable de retourner un null ce qui m'amène à la conclusion qu'il n'est pas appelé. De plus, lorsque je déclare myFilteredFoos
comme ceci:
Queryable myFilteredFoos;
L'appel de retour se plaint que myFilteredFoos peut être utilisé avant son initialisation.
En effet, le code de la méthode Returns
est évalué immédiatement; c'est-à-dire lorsque la méthode Setup
est invoquée.
Cependant, le rappel n'est pas appelé tant que la méthode GetByFilter
n'est pas appelée.
Heureusement, la méthode Returns
est surchargée afin que vous puissiez également différer son exécution:
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, car vous pouvez simplement obtenir la valeur du paramètre directement dans la méthode Returns
:
mockObject.Setup(m => m.GetByFilter(It.IsAny<IFilter>()))
.Returns((IFilter filter) =>
filter.FilterCollection(objects).Cast<IFooBar>());
Vous pouvez simplement prendre le paramètre dans la valeur de retour ...
mockObject
.Setup(m => m.GetByFilter(It.IsAny<IFilter>()))
.Returns((IFilter filter) =>
{
myFilteredFoos = filter.FilterCollection(objects);
return myFilteredFoos.Cast<IFooBar>();
});