Imaginez cette classe
public class Foo {
private Handler _h;
public Foo(Handler h)
{
_h = h;
}
public void Bar(int i)
{
_h.AsyncHandle(CalcOn(i));
}
private SomeResponse CalcOn(int i)
{
...;
}
}
Mo (q) cking Handler dans un test de Foo, comment pourrais-je vérifier ce qui Bar()
est passé _h.AsyncHandle
?
Réponses:
Vous pouvez utiliser la méthode Mock.Callback:
Si vous voulez seulement vérifier quelque chose de simple sur l'argument passé, vous pouvez également le faire directement:
la source
Callback<>()
méthode Moq générique . Par exemple, si votre méthode avait la définitionHandler.AnsyncHandle(string, SomeResponse)
, vous en auriez besoin/* ... */.Callback<string, SomeResponse>(r => result = r);
. Je n'ai pas trouvé cela explicitement indiqué dans de nombreux endroits, alors j'ai pensé l'ajouter ici./* ... */.Callback<string, SomeResponse>((s1, s2) => { str1 = s1; result = s2});
.Callback((string s1, SomeResponse s2) => /* stuff */ )
Capture.In
assistant intégré ?La réponse de Gamlor a fonctionné pour moi, mais j'ai pensé développer le commentaire de John Carpenter car je cherchais une solution impliquant plus d'un paramètre. J'ai pensé que d'autres personnes qui tombaient sur cette page pourraient être dans une situation similaire. J'ai trouvé cette information dans la documentation Moq .
Je vais utiliser l'exemple de Gamlor, mais faisons comme si la méthode AsyncHandle prend deux arguments: un
string
et unSomeResponse
objet.Fondamentalement, il vous suffit d'en ajouter un autre
It.IsAny<>()
avec le type approprié, d'ajouter un autre type à laCallback
méthode et de modifier l'expression lambda le cas échéant.la source
La méthode Callback fonctionnera certainement, mais si vous faites cela sur une méthode avec beaucoup de paramètres, cela peut être un peu verbeux. Voici quelque chose que j'ai utilisé pour retirer une partie du passe-partout.
Voici la source d'ArgumentCaptor:
la source
La réponse de Gamlor fonctionne, mais une autre façon de le faire (et que je considère plus expressive dans le test) est ...
Vérifier est très puissant et vaut la peine de prendre le temps de s'y habituer.
la source
L'alternative consiste également à utiliser la
Capture.In
fonctionnalité dumoq
. C'est lamoq
fonction OOTB qui permet la capture d'arguments dans la collection.la source
Callback
OMI. Étant donné que vous utilisez Capture directement dans la liste de paramètres, il est beaucoup moins sujet aux problèmes lors de la refactorisation de la liste de paramètres d'une méthode et rend donc les tests moins fragiles. Avec Callback, vous devez garder les paramètres passés dans Setup en synchronisation avec les paramètres de type utilisés pour Callback, et cela m'a certainement causé des problèmes dans le passé.Vous pourriez utiliser
It.Is<TValue>()
matcher.la source
Cela fonctionne également:
la source
Beaucoup de bonnes réponses ici! Optez pour l'ensemble de fonctionnalités Moq prêt à l'emploi jusqu'à ce que vous ayez besoin de faire des affirmations sur plusieurs paramètres de classe passés à vos dépendances. Si vous vous retrouvez dans cette situation, la fonction de vérification Moq avec les correspondants It.Is ne fait pas un bon travail pour isoler l'échec du test, et la méthode de retour / rappel des arguments ajoute des lignes de code inutiles à votre test (et les longs tests sont interdits pour moi).
Voici l'essentiel: https://gist.github.com/Jacob-McKay/8b8d41ebb9565f5fca23654fd944ac6b avec une extension Moq (4.12) que j'ai écrite qui donne une manière plus déclarative de faire des affirmations sur les arguments passés aux mocks, sans les inconvénients mentionnés ci-dessus. Voici à quoi ressemble la section Vérifier maintenant:
Je serais ravi si Moq fournissait une fonctionnalité qui accomplissait la même chose tout en étant aussi déclarative et en fournissant l'isolement d'échec que cela permet. Doigts croisés!
la source