6
votes

Pourquoi n'y a-t-il pas une fois.Alement dans le MOQ?

avec MOQ, il est possible de vérifier qu'une méthode est jamais forte> appelée à certains arguments (c'est-à-dire des arguments satisfaisant certains prédicats) à l'aide de fois. N'ayez jamais code>.

Mais comment vérifier cela, pas de matières combien de fois une méthode est appelée, elle est toujours forte> appelée à certains arguments? P>

La valeur par défaut semble être fois.atleastonce code>. p>

Il n'y a pas de fois.always code>. Est-ce que je manque quelque chose d'évident? Merci! P>

Edit: J'ai publié une suggestion à la liste de diffusion MOQ la semaine dernière, mais cela n'a pas l'impression que cela ait été modéré. Je posterai des mises à jour ici. P>

Edit: un exemple. Dis que je teste une classe qui génère des documents XML. Je veux m'assurer que seuls les documents valides sont générés. En d'autres termes, testez que la dépendance de l'auteur est seulement jamais em> donné des documents valides, avec un numéro de séquence valide, pour écrire. P>

should_only_write_valid_xml_documents

Mock.Get(this.writer).Verify(
    w => w.Write(
        It.Is<XDocument>(doc => XsdValidator.IsValid(doc)),
        It.Is<int>(n => n < 3)),
    Times.Always);


3 commentaires

"TOUJOURS" implique de savoir combien de fois "toujours" est, et si vous savez que pourquoi ne pas utiliser les temps (n) à la place?


Non, ce n'est pas un peu le point de la question. Imaginez une méthode appelée dans une boucle dont la taille est déterminée de manière dynamique.


Ensuite, à l'intérieur de l'itération de la boucle, je vérifierais que la méthode a été appelée une fois, encore et encore et encore. Cela suppose que la boucle est dans le code de test. Si c'est dans le code à tester à la place, je repenserais à la testabilité afin que je puisse accrocher au code de boucle pour vérifier chaque appel de méthode.


4 Réponses :


8
votes

et combien de fois est 'toujours?' MOQ conserve la trace de toutes les fois qu'une certaine méthode est appelée à certains arguments, puis utilise ce nombre pour comparer les temps. Néanmoins, fois.atleastonce, etc.

Donc, si une méthode est exécutée 4 fois et vous l'avez définie. à 'Times.always' Qu'est-ce que cela signifie même?

fois. N'ayez jamais vérifiant pour vous assurer que le nombre est zéro.

fois.atleastonce vérifierait que le nombre est supérieur ou égal à un.

Times.always vérifierait que le nombre est ....

Vous pouvez déterminer le nombre de fois qu'il devrait fonctionner par programme, puis faire quelque chose comme: xxx

Mais il n'y a aucun moyen pour MOQ de savoir ce que «toujours» signifie.


7 commentaires

Je ne vois pas comment cela peut être vrai. MOQ sait ce que "jamais" signifie - "toujours" est l'inverse de "jamais". Le nombre que vous mentionnez serait simplement comparé au nombre total d'invocations, par opposition à zéro.


@Petemontgomery MOQ sait ce que "jamais" signifie parce que cela signifie zéro. "TOUJOURS" est un nombre ambigus qui pourrait inclure tout entier positif. Vouloir que MOQ teste à chaque fois qu'une méthode est appelée, elle a été appelée, semble être un point de théâtre. Si vous effectuez une exécution plusieurs fois (comme dans une boucle), gardez simplement une variable autour de celle qui représente le nombre de fois que cela aurait dû être appelé et exécuter un test qui passe à des moments. Exactement (NumTimesshouldrun).


Hmm, j'ai bien peur de penser que cela n'est pas contradictoire ou mal compris le point de la question. Je parle de tester que chaque fois qu'une méthode est appelée, elle s'appelle avec certains arguments . Voir les autres réponses.


@Petemontgomery Compte tenu du comportement actuel, il pourrait être déroutant de chuter dans une fois. La méthode "Vérifier" la méthode des États "vérifie qu'une invocation spécifique correspondant à l'expression donnée a été réalisée sur la simulation." Ajout d'une fois. La valeur annonceuse changerait fondamentalement quelle est la méthode de vérification. Pour toutes les autres valeurs, ce serait normal mais pour les horaires, il vérifiera également que cela n'appelle pas la méthode avec d'autres arguments. Si vous deviez utiliser vérifier au sens strict, «toujours» serait un terme ambigu (comme expliqué dans ma réponse) et donc de ne pas avoir de sens.


Non-sens, vous pourriez dire exactement la même chose à propos de fois.


Cependant, je prends ce point: "Parmi les temps.est, il serait également en train de vérifier que cela n'appelle pas la méthode avec d'autres arguments" ... c'est vraiment vrai - mais c'est exactement ce que je pense pourrait être utile à Vérifier. (Mais je ne vois pas comment cela change la sémantique de "vérifier" plus de temps.nest!) Pete


@Petemontgomery Times.Ne signifie juste zéro. Donc, comme vous vérifiez, vous vérifiez l'invocation de l'expression donnée zéro fois. C'est le même comportement que les autres «horaires» en ce sens qu'il teste l'invocation de l'expression donnée et rien d'autre (c'est-à-dire invocation de la même méthode avec différents arguments). Si vous ajoutez des horaires. Vous changez de sorte que vérifiez que vérifiez ou vérifiant l'expression a été invoquée «toujours» de temps (ambigu). En revanche, une "fois" pourrait être ajoutée car elle ne change pas ce que vérifie la vérification et n'est pas une détermination ambiguë.



0
votes

Ma recommandation serait de créer une correspondance «debout» pour la méthode avec elle. Vous pouvez alors vérifier les temps. N'enregistrez jamais sur cette correspondance, qui devrait toujours avoir été remplacée par la correspondance plus spécifique.


1 commentaires

Pourriez-vous montrer comment faire cela? (Les appels à vérifier ne font pas "tomber" si c'est ce que vous voulez dire - ils sont indépendants, jusqu'à ce que je puisse voir.) Ou voulez-vous dire réécrire le test pour utiliser les temps d'utilisation. Parfois, ce n'est pas possible, car vous devriez spécifier tous les arguments non valides possibles. Bravo, Pete.



3
votes

On dirait que vous voulez que vous vouliez un comportement "strict". Si la méthode est appelée avec quelque chose d'autre que les paramètres attendus, le test échouera.

Ceci est disponible en MOQ: P>

var mock = new Mock<IFoo>(MockBehavior.Strict);


1 commentaires

Bien sûr - mais s'il existait, cette option me permet d'éviter la douleur de passer à une simulation stricte et la configuration supplémentaire qu'elle implique.



2
votes

Vous pouvez appliquer une inversion de la logique pour vérifier toujours.

par exemple: p>

Disons que vous souhaitez effectuer la vérification suivante: P>

mock.Verify(x => x.Method(It.Is<int>(i => i != 10)), Times.Never());


2 commentaires

Bonjour, la motivation exacte pour ma question est que, bien que vous puissiez le faire dans des cas simples, comme votre exemple, vous ne pouvez pas le faire dans tous les cas. Par exemple: Vérifier une méthode n'est jamais appelée avec un document XML qui satisfait à certains critères. Vous ne pouvez pas écrire tous les documents XML possibles qui ne satisfont pas à ces critères. Vous ne pouvez donc pas "inverser" la vérification à utiliser des temps.


Désolé, je suis totalement tort sur ce dernier point - je viens de réaliser que vous en général peut inverser et utiliser des temps. N'ayez-ce que vous avez fourni uniquement un argument à la fois.