Mockito: de retour de la méthode de la valeur dépend d'autres méthode appelée
Dans mon unité de test, j'ai besoin de simuler un interface entre les différentes méthodes a nextItem()
et isEmpty()
méthodes:
public interface MyQueue {
Item nextItem();
boolean isEmpty();
//other methods
...
}
Mon exigence pour la maquette, c'est que isEmpty()
initialement doit retourner false, mais après nextItem()
a été appelé isEmpty()
doit retourner true. Donc je suis moqueur, une file d'attente avec un seul point.
- Quelle est la façon la plus simple à mettre en œuvre ce genre de fantaisie avec mockito?
- Puis-je mettre en œuvre exigence supplémentaire: l'appel de
nextItem()
deuxième, troisième et ainsi de suite entraînera dans un type spécifique d'exception?
P. S. je ne veux pas donner de la mise en œuvre complète de mon interface pour le test, parce que d'autres méthodes, résultant en dur-pour-comprendre et commenté code.
Vous pouvez avoir une variable booléenne que vous pouvez passer à true lorsque vous entrez nextItem()
pouvez-vous suggérer la mise en œuvre qui n'est pas explicite?
pouvez-vous suggérer la mise en œuvre qui n'est pas explicite?
OriginalL'auteur pavel_kazlou | 2012-09-29
Vous devez vous connecter pour publier un commentaire.
Vous pouvez le faire avec thenAnswer(), une fonction Mockito documentation voit que controversée:
Encore un autre controversé qui n'a pas été inclus dans Mockito à l'origine. Nous vous recommandons d'utiliser de simples cogner avec toReturn() ou toThrow (). Ces deux devrait être juste assez pour test/test-drive tout clean & code simple.
Voici thenAnswer:
called
, qui est utilisé uniquement dans une méthode de test. Nous ne pouvons pas mettre de la déclaration decalled
à l'intérieur de la méthode d'essai, car il est alors nécessaire de finale.OriginalL'auteur Assen Kolov
Voici un exemple simple:
willReturn(false, true)
signifie: retourfalse
sur la première invocation ettrue
sur la deuxième.InOrder
objet est utilisé pour vérifier l'invocation de la commande. Modifier l'ordre ou supprimernextItem()
appel et le test échouera.Alternativement, vous pouvez utiliser cette syntaxe:
Si vous avez besoin d'encore plus forte, se moquant de la sémantique, vous pouvez introduire l'artillerie lourde - custom réponse de rappel:
Mais cela peut facilement conduire à désuète code de test, utiliser avec prudence.
Enfin, vous pouvez espion votre objet réel par se moquer uniquement les méthodes sélectionnées.
isEmpty()
ne sera pas appelé plus d'une fois avant denextItem()
est appelé.malheureusement, même l'artillerie lourde n'a pas la force d'interaction entre les méthodes - exigences sont imposées séparément sur chaque méthode et sont uniquement basés sur un certain nombre d'invocations...
voir ma solution ci-dessous, mais l'artillerie lourde peut appliquer ce genre de chose si vous utilisez une Réponse qui dépend d'une autre Réponse. Elle peut alors prendre des décisions fondées sur d'autres choses qui peuvent ou peuvent ne pas avoir été invoquée devant elle.
eh bien, vous pouvez utiliser la même réponse de l'objet pour les deux méthodes. Vous pouvez aussi avoir à répondre à des objets de partage certains de l'état global. Mais cela devient de laide pour coller ici...
Notez que si vous préférez ne pas utiliser le BDDMockito méthodes, vous pouvez écrire ce que
when(mock.isEmpty()).thenReturn(false, true);
. Notez également que la troisième et les suivantes invocations deisEmpty()
est également de retourtrue
- lorsque vous liste plusieurs valeurs de retour aprèsthenReturn
ouwillReturn
, la dernière valeur de la liste peut être retourné à plusieurs reprises.OriginalL'auteur Tomasz Nurkiewicz
Vous pouvez fournir une Réponse personnalisée implémentations dont l'un dépend de l'autre:
et ensuite l'utiliser:
Vous pouvez l'ajuster comme je n'ai pas testé ce code, mais l'approche doit être ce dont vous avez besoin.
vous pouvez la rendre un peu moins prolixe en utilisant anonyme classes au lieu d'déclaré, mais l'idée est toujours la même.
OriginalL'auteur Matt
Je me rends compte que vous avez explicitement écrit que vous ne souhaitez pas utiliser une pleine mise en œuvre de MyQueue, mais, pour être honnête, ce serait la première chose que je ferais.
En fait, j'ai régulièrement fournir 'maquette' implémentations raisonnablement interfaces complexes/objets dans le but de faire des tests plus facile à tester. Je ne suis pas le seul à penser que: Spring Framework fournit de nombreuses moqué des versions des objets complexes (MockHttpServletRequest, MockHttpServletResponse, etc.), par exemple.
Dans ce cas, j'aimerais éviter d'encombrer mon test et de fournir à cette classe, soit dans un emballage séparé ou même dans le code de production.
Un MockQueue serait de faire vos tests beaucoup plus lisible que les autres (mais correct) réponses suggèrent ici.
MyQueue mock = new MockUp<MyQueue>() { boolean nextItemCalled; @Mock boolean isEmpty() { return nextItemCalled; } @Mock Item nextItem() { nextItemCalled = true; return someItem; } }.getMockInstance();
Que faire si la mise en œuvre doit être changé pour différents tests? Vous devez ensuite vous présenter quelques OO conception de l'héritage ou de la composition pour les implémentations. Je pense que l'approche avec les moqueries uniquement les méthodes dont j'ai besoin pour chaque test de la garde des tests unitaires simples et faciles à comprendre. - Je établir le contrat qui ma classe testée doit être conforme, le code qui n'est pas liée doit être évitée. En passant, merci pour ce genre de réponse qui implique une discussion du concept, je suis très intéressé par votre proposition, mais à l'heure actuelle ne peut pas comprendre les avantages.
Eh bien, vous vous moquez du
Collection
interface? J'ai vu des gens le faire, mais qui ne sonne pas comme une bonne idée pour moi. Une interface appeléeQueue
donne quelques hypothèses de base pour les clients de l'interface. Même si la mise en œuvre peut varier, le comportement général devrait être plus ou moins la même chose du point de vue du client classes. Avez-vous un exemple plus spécifique d'une situation où cela ne fonctionnerait pas?se moquant de la Collecte n'est pas une bonne idée, car il ya beaucoup de bien testé implémentations, je peux utiliser fiable pour former les exigences. La situation inverse est quand j'ai besoin d'utiliser perso classe/interface de dépendance pour la classe testée. Si j'utilise mon propre implémentations dans le test, bien que cela signifie que je ne suis pas de test de classe cible dans l'isolement, mais, ensemble, avec la File d'attente de la dépendance. Cela signifie que la réussite d'un test peut être cassé, ou (ce qui est pire) n'a pas de test peut être corrigé en modifiant le code pas en classe testée mais dans sa dépendance.
Lors de l'utilisation de vos propres implémentations, vous avez deux options: soit vous fournir un "trop simple de briser" la mise en œuvre juste pour vos tests (c'est en gros MockQueue), et des tests, il ne devrait pas vraiment être nécessaire. Ou, vous réutilisez un réel, valide & testé, la mise en œuvre. En fait, j'ai exactement ce genre d'objets dans mon projet en cours. Un DataHistory classe, assez complexe et, par conséquent soigneusement testé, je réutiliser dans mes autres tests. Je pense que cela fonctionne parce que son comportement est assez simple à comprendre (ajouter des choses, de retour dans un certain ordre), un peu comme une Collection, vraiment.
OriginalL'auteur Eric
Vous pouvez dire mockito à répondre différemment sur les appels successifs à la même moqué de méthode en utilisant les techniques décrites dans le mockito docs.
fera le
isEmpty()
de retour d'appel vrai que sur le premier appel, etfera
nextItem()
retourner quelque chose sur le premier appel et de lever une exception lors des appels ultérieurs.Je ne sais pas qu'il est possible de rendre le résultat de l'une de ces méthodes dépendent de séquençage d'appels de l'autre. Si il est effectivement possible, je suis sûr que c'est beaucoup plus complexe.
isEmpty()
est appelée qu'une seule fois avant denextItem()
est appelé.Oui, ça fonctionne, mais comme il est noté dans la réponse que je ne suis pas sûr que c'est possible de faire mieux.
OriginalL'auteur Don Roby
Vous pouvez faire une méthode utilitaire, et ensuite l'utiliser partout où vous voulez.
Simple d'utilisation:
Dans ce cas, vous n'avez pas besoin de variables et il est plus "Mockito style".
OriginalL'auteur dvelopp